Closed lucaslorentz closed 3 years ago
Very cool! A couple other projects to be aware of:
Generally speaking, all of your planned items are things that I think would be very helpful for the project. There may be potential opportunities for alignment regarding some of the projects mentioned above as well. Let us know how we can help.
Thanks @cgillum
I would need other storage implementations, like DurableTask.SqlServer, to implement some additional contracts I defined:
Any thoughts about those contracts? I wonder if we can incorporate them in official durable task packages. I can create a PR and we discuss it further there.
@lucaslorentz this is a very ambitious project, I like it! It's great to see you have some experience with Cadence as well since I think it would be good to adopt some of their learnings back into DTFx.
Regarding IExtendedOrchestrationService
and INameVersionInfo[]
. I like this idea because of how it would allow you to isolate particular activities and orchestrations to specific workers. However, existing providers like DT.ServiceBus and DT.AzureStorage have a shared queue model where all orchestration events and tasks go through a shared set of queues. There's also the problem of being able to filter messages without any embedded name/version information. Should I assume that this interface is only intended for newer SQL-based storage providers?
How far along are your prototype providers? I think I'd feel okay taking some of these extensions into DT.Core if you think they are stable.
Also, have you considered abstract base classes over interfaces as a way to continue extending the functionality without needing to introduce even more interfaces (i.e. to avoid breaking changes)?
Actually, I have no practical Cadence experience, just read docs and pieces of source code.
Should I assume that this interface is only intended for newer SQL-based storage providers?
That's a fair assumption. I think it would be implemented first by new SQL-based providers. But I think other providers could follow in the future as well.
When implementing that on SQL I found out that using IN
and OR
to filter queues affects the index scan and consequentially locks scanned rows from "other queues".
The approach ended up doing is to try to dequeue from each one at random order. I guess it would be possible to implement this approach on any "pull to dequeue" provider?
How far along are your prototype providers?
The providers are functional.
The samples folder has a fully working example of a microservices architecture like this diagram. Which involves EFCore + GRPC providers.
But I haven't test anything on a real application or production environment. A lot of testing and fine tunning is still required.
Also, have you considered abstract base classes over interfaces as a way to continue extending the functionality without needing to introduce even more interfaces (i.e. to avoid breaking changes)?
I think it might be a better option indeed for an evolving contract.
I can use C# 8 default interface implementation as well in my repo. Not sure if Durable Task can use it because it requires netstandard2.1.
@cgillum
There's also the problem of being able to filter messages without any embedded name/version information
That's only the case for raising events and termination of orchestrations, right?
Providers that use real queues could query the name/version of the instance before putting the message in the queue.
Not optimal, but I don't see many use cases as well with intensive message sending to orchestrations, I would assume it's acceptable to add delays to those operations.
Edit: I guess activity completions also falls under this scenario, which would affect overall performance a bit. But that could be solved by including the Orchestration queue name in the activity message.
@cgillum
In the end, I implemented the way I described above: In SendTaskOrchestrationMessage I query the current queue (name+version) of the target instanceId. During orchestration task completion it's possible to know the queue for all messages to be sent. And I store reply queue information within every task activity message created.
This approach could be implemented in Azure Storage and Service Bus.
I'm stabilizing the project with tests and I will continue exploring the distributed workers concept.
I'm creating a project that concisely extends what Durable Task project already delivers: https://github.com/lucaslorentz/durabletask-extensions
This would be the scope of the project:
I still don't know how far I will go with that project.
So I would like to get some feedback if it would be useful to anyone, or if it conflicts with other projects or plans.
Screenshot of history visualization in UI :-)