How to fix laravel no command 'Redis::throttle'? - laravel

I just use doc example,but get the error
exception 'Predis\ClientException' with message 'Command 'THROTTLE' is not a registered Redis command.
I havce search a lot about redis command,but nothing about throttle.
public function handle()
{
// Allow only 2 emails every 1 second
Redis::throttle('my-mailtrap')->allow(2)->every(1)->then(function () {
$recipient = 'steven#example.com';
Mail::to($recipient)->send(new OrderShipped($this->order));
Log::info('Emailed order ' . $this->order->id);
}, function () {
// Could not obtain lock; this job will be re-queued
return $this->release(2);
});
}
What should I do?Any help,Thanks!

throttle method is defined in Illuminate/Redis/Connections/PredisConnection.
The Redis facade allows for you to get the connection using
Redis::connection()
->throttle('my-mailtrap')
//...
http://laravel.com/docs/5.8/redis

Related

How do I run multiple jobs with a given IJobConsumer within a single service instance?

I want to be able to execute multiple jobs concurrently on a Job Consumer. At the moment if I run one service instance and try to execute 2 jobs concurrently, 1 job waits for the other to complete (i.e. waits for the single job slot to become available).
However if I run 2 instances by using dotnet run twice to create 2 separate processes I am able to get the desired behavior where both jobs run at the same time.
Is it possible to run 2 (or more) jobs at the same time for a given consumer inside a single process? My application requires the ability to run several jobs concurrently but I don't have the ability to deploy many instances of my application.
Checking the application log I see this line which I feel may have something to do with it:
[04:13:43 DBG] Concurrent Job Limit: 1
I tried changing the SagaPartitionCount to something other than 1 on instance.ConfigureJobServiceEndpoints to no avail. I can't seem to get the Concurrent Job Limit to change.
My configuration looks like this:
services.AddMassTransit(x =>
{
x.AddDelayedMessageScheduler();
x.SetKebabCaseEndpointNameFormatter();
// registering the job consumer
x.AddConsumer<DeploymentConsumer>(typeof(DeploymentConsumerDefinition));
x.AddSagaRepository<JobSaga>()
.EntityFrameworkRepository(r =>
{
r.ExistingDbContext<JobServiceSagaDbContext>();
r.LockStatementProvider = new SqlServerLockStatementProvider();
});
// add other saga repositories here for JobTypeSaga and JobAttemptSaga here as well
x.UsingRabbitMq((context, cfg) =>
{
var rmq = configuration.GetSection("RabbitMq").Get<RabbitMq>();
cfg.Host(rmq.Host, rmq.Port, rmq.VirtualHost, h =>
{
h.Username(rmq.Username);
h.Password(rmq.Password);
});
cfg.UseDelayedMessageScheduler();
var options = new ServiceInstanceOptions()
.SetEndpointNameFormatter(context.GetService<IEndpointNameFormatter>() ?? KebabCaseEndpointNameFormatter.Instance);
cfg.ServiceInstance(options, instance =>
{
instance.ConfigureJobServiceEndpoints(js =>
{
js.SagaPartitionCount = 1;
js.FinalizeCompleted = true;
js.ConfigureSagaRepositories(context);
});
instance.ConfigureEndpoints(context);
});
});
}
Where DeploymentConsumerDefinition looks like
public class DeploymentConsumerDefinition : ConsumerDefinition<DeploymentConsumer>
{
protected override void ConfigureConsumer(IReceiveEndpointConfigurator endpointConfigurator,
IConsumerConfigurator<DeploymentConsumer> consumerConfigurator)
{
consumerConfigurator.Options<JobOptions<DeploymentConsumer>>(options =>
{
options.SetJobTimeout(TimeSpan.FromMinutes(20));
options.SetConcurrentJobLimit(10);
options.SetRetry(r =>
{
r.Ignore<InvalidOperationException>();
r.Interval(5, TimeSpan.FromSeconds(10));
});
});
}
}
Your definition should specify the job consumer message type, not the job consumer type:
public class DeploymentConsumerDefinition : ConsumerDefinition<DeploymentConsumer>
{
protected override void ConfigureConsumer(IReceiveEndpointConfigurator endpointConfigurator,
IConsumerConfigurator<DeploymentConsumer> consumerConfigurator)
{
// MESSAGE TYPE NOT CONSUMER TYPE
consumerConfigurator.Options<JobOptions<DeploymentCommand>>(options =>
{
options.SetJobTimeout(TimeSpan.FromMinutes(20));
options.SetConcurrentJobLimit(10);
options.SetRetry(r =>
{
r.Ignore<InvalidOperationException>();
r.Interval(5, TimeSpan.FromSeconds(10));
});
});
}
}

Is there a way to automatically assign the data by the schedule date or time in laravel, flutter or dart?

Let say I want to post a new data through api. For eg, I am assigning "Milo" as a name on October 10.
{
"name": "Milo",
"time": 3
}
Then 3 days later, on October 13, I want "Cola" to be the name automatically, not "Milo". I don't want to assign it manually. I want to automate it.
Is there a way to do it in laravel, flutter or dart?
Edited...
I've found a way using laravel task scheduling. I don't know that'll work or not in production. Please enlighten me.
protected function schedule(Schedule $schedule)
{
$schedule->call(function () {
foreach (Ad::all() as $ad) {
if (Carbon::now('Asia/Yangon')->format("Y-m-d") ==
$ad->expire) {
$ad->serial = 0;
$ad->name = "null";
$ad->site = "null";
$ad->expire = "expired";
$result = $ad->save();
if ($result) {
return ["killed this one" => $ad];
} else {
return ["error"];
}
}
}
})->everyMinute();
}
I've seen a post which says "to test it run"
php artisan schedule:run
I test it successfully but it keeps saying
and "If it works add
***** php /path/to/artisan schedule:run >> /dev/null 2>&1
to your cron."
I don't know what cron means. Please enlighten me. I want to make sure the schedule code works in production. I am using windows os.
you can use timer in initState
var data = { name: "alex", time: 3 };
timer = new Timer.periodic(new Duration(days: data['time']), (Timer timer) async {
setState(() {
name = "something"
});
});
it will execute after 7 days
use Laravel Task Scheduling:
protected function schedule(Schedule $schedule)
{
$schedule->call(function () {
// change "Milo" to "Cola" here
})->daily();
}

MassTransit endpoint name is ignored in ConsumerDefinition

The EndpointName property in a ConsumerDefinition file seems to be ignored by MassTransit. I know the ConsumerDefinition is being used because the retry logic works. How do I get different commands to go to a different queue? It seems that I can get them all to go through one central queue but I don't think this is best practice for commands.
Here is my app configuration that executes on startup when creating the MassTransit bus.
Bus.Factory.CreateUsingAzureServiceBus(cfg =>
{
cfg.Host(_config.ServiceBusUri, host => {
host.SharedAccessSignature(s =>
{
s.KeyName = _config.KeyName;
s.SharedAccessKey = _config.SharedAccessKey;
s.TokenTimeToLive = TimeSpan.FromDays(1);
s.TokenScope = TokenScope.Namespace;
});
});
cfg.ReceiveEndpoint("publish", ec =>
{
// this is done to register all consumers in the assembly and to use their definition files
ec.ConfigureConsumers(provider);
});
And my handler definition in the consumer (an azure worker service)
public class CreateAccessPointCommandHandlerDef : ConsumerDefinition<CreateAccessPointCommandHandler>
{
public CreateAccessPointCommandHandlerDef()
{
EndpointName = "specific";
ConcurrentMessageLimit = 4;
}
protected override void ConfigureConsumer(
IReceiveEndpointConfigurator endpointConfigurator,
IConsumerConfigurator<CreateAccessPointCommandHandler> consumerConfigurator
)
{
endpointConfigurator.UseMessageRetry(r =>
{
r.Immediate(2);
});
}
}
In my app that is sending the message I have to configure it to send to the "publish" queue, not "specific".
EndpointConvention.Map<CreateAccessPointsCommand>(new Uri($"queue:specific")); // does not work
EndpointConvention.Map<CreateAccessPointsCommand>(new Uri($"queue:publish")); // this does work
Because you are configuring the receive endpoint yourself, and giving it the name publish, that's the receive endpoint.
To configure the endpoints using the definitions, use:
cfg.ConfigureEndpoints(provider);
This will use the definitions that were registered in the container to configure the receive endpoints, using the consumer endpoint name defined.
This is also explained in the documentation.

Stripe PHP Best way to debug an SignatureVerificationException with Stripe-cli

I created a webhook to get informations about checkout sessions :
public function stripeWebhookCheckout(Request $request)
{
\Stripe\Stripe::setApiKey(env("STRIPE_SECRET"));
// You can find your endpoint's secret in your webhook settings
$endpoint_secret = 'whsec_fVBkAmCztUTacQKZiyjmcq6QQrl8lKL1';
$payload = #file_get_contents('php://input');
$sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
$event = null;
try {
$event = \Stripe\Webhook::constructEvent(
$payload,
$sig_header,
$endpoint_secret
);
} catch (\UnexpectedValueException $e) {
// Invalid payload
http_response_code(400);
exit();
} catch (\Stripe\Exception\SignatureVerificationException $e) {
// Invalid signature
http_response_code(400);
exit();
}
// Handle the checkout.session.completed event
if ($event->type == 'checkout.session.completed') {
$session = $event->data->object;
// Fulfill the purchase...
handle_checkout_session($session);
$stripeSessionId = $session['id'];
if (isset($stripeSessionId)) {
$payment = Payment::where('stripe_sessioncheckout_id', '=', $stripeSessionId)->first();
$payment->status = "success";
$payment->data = $session;
$payment->save();
}
}
http_response_code(200);
}
I use stripe-cli to test my webhook in local. And i have this kind of result
$ stripe listen --forward-to jvlb.test/api/stripe/webhook/checkout
> Ready! Your webhook signing secret is whsec_sc9Gh9A6zx3IOfBpH62F9DdPYIhSUYtw (^C to quit)
2019-11-28 16:19:06 --> charge.succeeded [evt_1FjsW5FIYszmshR0eGSB9GDo]
2019-11-28 16:19:06 <-- [400] GET https://jvlb.test/api/stripe/webhook/checkout [evt_1FjsW5FIYszmshR0eGSB9GDo]
To debug it i changes the http_response_code(400) and I realised it generate a SignatureVerificationException.
My question is, how can i debug this ? Is it the $_SERVER['HTTP_STRIPE_SIGNATURE'] who is wrong ?
Thanks
i found a solution, if it can help people in the future :
I made a mistake in the way i use stripe-cli, i forgot "https://".
The good way is :
stripe listen --forward-to https://jvlb.test/api/stripe/webhook/checkout
And then i had few error of code to manage. I just used the tail command on my log file
tail -f storage/logs/laravel-2019-11-29.log

TokenMismatch error when run codeception test

I am getting this error in my log file when I run codeception test case. How to fix this?
Code:
public function testUpdatePhone(FunctionalTester $I)
{
$I->wantTo('Test update phone');
$I->sendPUT('/admin/phone/100', [
'label' => 'My new label'
]);
$I->see('Phone Number updated successfully.');
}
Command:
./vendor/bin/codecept run
tests/functional/AdminPhoneTestCest.php:testUpdatePhone
Error in Log file:
[2015-06-06 05:34:02] local.ERROR: exception
'Illuminate\Session\TokenMismatchException' in
/var/www/xxxx/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php:46
Thanks in advance :)
This issue has been fixed by adding middleware method as follows
public function handle($request, Closure $next)
{
if ($request->header('user-agent') == 'Symfony2 BrowserKit') {
return $next($request);
}
throw new TokenMismatchException;
}
Reference: https://laracasts.com/discuss/channels/general-discussion/latest-v5-laravelframework-csrfmiddleware-changes-broke-codeception-functional-tests
If you're using phantomjs, you will need to ensure you have clear_cookies: true in your settings as the normal restart: true doesn't seem to be supported for phantomjs, so it uses the same token which is invalid in subsequent tests.

Resources