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
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));
});
});
}
}
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();
}
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.
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
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.