Closed Tsjunne closed 2 years ago
Yes I think it would be possible, but there's no API that helps with configuring it at the moment.
Rebus receives messages using "workers", and then incoming messages are dispatched by calling a "pipeline invoker" – you can see the lines responsible here.
As you can probably see, the design fully supports the "here, Rebus, take this message and handle it" scenario 🙂
Hi @mookid8000, any guidelines on how we can achieve this?
I tried to still use the ServiceBusTrigger
in my Function and then dispatch the message to the Rebus pipeline, but I had no luck with it yet.
Thanks!
Can you tell me how far you got?
I know that e.g. DefaultPipelineInvoker
is internal (and possibly other related classes), so unfortunately it's not just
using var scope = new RebusTransactionScope();
var transportMessage = (...);
var invoker = new DefaultPipelineInvoker(...);
var context = new IncomingStepContext(transportMessage, scope.TransactionContext);
await invoker.Invoke(context);
await scope.CompleteAsync();
buuut I don't think you would need to copy that many lines of code to emulate that in a function....
I have not found a way to create a Rebus pipeline and send the message through it. Classes required to build a pipeline are internal (for example the JSON serializers), and I believe this is because the Rebus' fluent configuration API hides the actual classes and only exposes extensions methods (for example UseNewtonsoftJson()
).
So it seems that to support this use case would require opening up some parts of the Rebus API to allow one to easily create a fully functional pipeline without an actual bus.
I also looked at StandardConfigurer<T>
in the hope I could use it to build a pipeline. But its constructor is internal, and its public static GetConfigurerFrom()
method requires an OptionsConfigurer
which also has an internal constructor.
I have implemented dispatch to Rebus message handlers via the Rebus pipeline for incoming messages using reflection to get the IPipelineInvoker
and by implementing a custom TransactionContext
. If IBus
would expose its IPipelineInvoker
as a public read-only property and if Rebus.Transactions.TransactionContext
were a public (sealed) class, then it would be much easier. @mookid8000 How do you feel about those changes?
Well, I can definitely see how the pipeline invoker would need to be made public for this to be really good.
Regarding the transactions context, you can easily have one by going
using var scope = new RebusTransactionScope();
var context = scope.TransactionContext; //< 👈 here it is 🙂
// do stuff here
await DispatchMessage(message, context, whatever);
// complete the transaction here
await scope.CompleteAsync();
So is this still an open issue? :) It doesn't seem to be possible. Or am I skipping relevant parts of the discussion?
I was browsing the web for some clues on how to effectively use Rebus to host message handlers in an Azure Function. There are many opportunities for cost savings on Azure when moving to serverless functions, but I hate to loose the added value of the Rebus pipeline. I fell upon an implementation for NServiceBus: https://docs.particular.net/samples/azure-functions/ So this is clearly possible from Azure Extensibility view.
Has this been done or tried before using Rebus? Is this even remotely possible in Rebus' current architecture?