Comments (8)
@chrisrichards I added a new feature in version 2.1.0 that you can check out here.
This addresses the type of scenario you described. Use the example in my previous comment but instead of dispatching the event with IDispatcher
you can queue an event to be broadcasted in the background:
this._queue.QueueBroadcast(new SalesOrderCompleted(salesOrderId));
from coravel.
Awesome! Will take a look when I can, thanks.
from coravel.
Thanks @chrisrichards for the kind words!
You are correct, invocable classes cant accept parameters when using the syntax in your example.
A working example might be something like this:
- Change your invocable to accept the
salesOrderId
as a constructor arg.
public class SalesOrderProcessor : IInvocable
{
private int _salesOrderId;
public SalesOrderProcessor(int salesOrderId)
{
this._salesOrderId = salesOrderId;
}
// Don't forget the async keyword ;)
public async Task Invoke(int salesOrderId)
{
var salesOrder = await _context.SalesOrders.FindAsync(this._salesOrderId);
// Do your stuff.
}
}
- Then queue it up like this:
var invocable = new SalesOrderProcessor (salesOrderId);
_queue.QueueAsyncTask(async () => await invocable.Invoke());
// This might work as a shortcut (I'm just writing all this off the top of my head)
_queue.QueueAsyncTask(invocable.Invoke);
Let me know if that works 👍
from coravel.
@chrisrichards Keep in mind that the sample above would mean you can't really schedule your invocable class - which you might not need anyways?
from coravel.
The SalesOrderProcessor has dependencies of it's own, so I'm just trying out:
- SalesOrderProcessor - no longer invocable
public class SalesOrderProcessor
{
private readonly DbContext _context;
public SalesOrderProcessor(DbContext context)
{
_context = context;
}
public async Task Process(int salesOrderId)
{
var salesOrder = await _context.SalesOrders.FindAsync(this._salesOrderId);
// Do your stuff.
}
}
- Queue it
// _processor is DI injected SalesOrderProcessor in the constructor
_queue.QueueAsyncTask(() => await _processor.Process(salesOrderId));
Is there any reason why a typed IInvocable is not present? Looking through the code, it looks like it should be possible to have an IInvocable where type T is the parameter type. The queue and scheduler would need to be updated to add methods that accept IInvocable.
from coravel.
The reason that an Invocable type that accepts a parameter doesn't exist is that Invocables are a ubiquitous type that can be queued, scheduled, etc. across the board. So they are designed to encapsulate an entire isolated "job".
In your case, this is exactly why the Events feature exists.
You could create an event SalesOrderCompleted
(or whatever the context is) that would be broadcasted to one or many listeners. One of them being ProcessSalesOrder
(which could use a more specific name).
Event
public class SalesOrderCompleted: IEvent
{
public int SalesOrderId { get; set; }
public SalesOrderCompleted(int salesOrderId)
{
this.SalesOrderId = salesOrderId;
}
}
Listener
public class ProcessSalesOrder: IListener<SalesOrderCompleted>
{
private DbContext _dbContext;
public ProcessSalesOrder(DbContext dbContext){
this._dbContext = dbContext;
}
public async Task HandleAsync(SalesOrderCompleted broadcasted)
{
var salesOrder = await _context.SalesOrders.FindAsync(broadcasted.SalesOrderId);
}
}
Broadcast
await _dispatcher.Broadcast(new SalesOrderCompleted(salesOrderId));
The only downside to this is it won't be queued.
In the event that you need it queued (it's a weird workaround) - create an invocable that launches this event (and would have the dispatcher injected into it's constructor).
This is a lot of work though - so I think your use case brings up a valid issue.
Should there be a new type? Or just a way to queue event broadcasting?
Or both? lol
from coravel.
Hi, not sure if this necromancy is allowed or if I should create a new ticket. But I like the idea of being able to pass parameters to a job to modify the execution so just wanted to bounce this idea.
I think something like this could support parameters to Invocables without changing the base behavior, I tried it out in a clone, if you would like to take a look I could do a PR.
public interface IInvocable<TParam> : IInvocable
where TParam : class
{
/// <summary>
/// Execute the logic/code for this invocable instance with the provided TParam.
/// </summary>
/// <param name="parameter">A class with parameters for this invocable.</param>
/// <returns></returns>
Task Invoke(TParam parameter);
/// <summary>
/// This should be a instance of TParam that is valid for running the Invoke method.
/// This will be provided as a paramter when the Invocable is scheduled without parameters or the parameter value is null.
/// </summary>
/// <returns></returns>
TParam Default { get; }
}
The user would have to provide a default parameter that is used when you schedule the job normally, then the Queue and Schedule could add new methods like:
public IScheduleInterval ScheduleWithParameter<T, TParam>(TParam parameter)
void QueueInvocableWithParameter<T, TParam>(TParam param)
Giving flexibility without making any breaking changes.
This would allow us to do things like this:
scheduler.ScheduleWithParameter<NewTestInvocable, NewTestParam>(new NewTestParam { SomeVal = 2 })
.EveryFiveSeconds();
scheduler.ScheduleWithParameter<NewTestInvocable, NewTestParam>(new NewTestParam { SomeVal = 3 })
.EveryThirtySeconds();
scheduler.Schedule<NewTestInvocable>()
.EveryTenSeconds();
from coravel.
Right now, you could do something like this:
scheduler.ScheduleAsync( async scheduler =>
var job = new MyJob();
job.WithParam(new TestParam(5)); // Just a method you added to your invocable;
await job.Invoke();
);
Or use events like mentioned in this thread.
But I get that the syntax you supplied is more straightforward. Will have to mull on that a bit 😋
from coravel.
Related Issues (20)
- Sample to show how to execute Task on demand in .NET core 7
- Using Dependency Injection with ScheduleAsync HOT 1
- Run Task One Another / Control Concurrency in Queues HOT 1
- Is Coravel good fit for Blazor Server? HOT 4
- Stop scheduled job HOT 2
- Cron Expressions that support Seconds
- Design/Run Time
- Add support for setting Sender in mailer
- Add support for adding attachments as LinkedResources in MailMessage HOT 1
- Dispatcher.Broadcast doesn't work correctly when my listener class implements more than one IListener<> interfaces HOT 1
- Worker Service with Scheduler doesn't execute IInvocable using EveryMinute().WeekDay() on a Friday. HOT 1
- Advanced cron expressions HOT 2
- Is it possible for a job (or something else) to know when the next execution is scheduled for? HOT 2
- Unwanted Clock Drift HOT 2
- Add throttling when queuing items
- Extend Coravel Schedule With CoravelJobAttrbutes
- Scheduler does not run until WEB API server receives its first HTTP Request HOT 7
- How to use Event Broadcasting in worker service
- Task, scheduled to run on the same second, are not run in order they were added. HOT 1
- Turn off logging "Coravel's scheduler is behind" HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from coravel.