Kotlin channel - is there a non-suspending receive? - kotlin

Apparently if we call channel.receive() against an empty channel, it suspends, which is exactly as documented here in official docs. Is there a way to immediately return a null instead, like what ConcurrentLinkedQueue's poll() does?

Yes, we can use tryReceive():
channel.tryReceive().getOrNull()

Related

GRPC future vs blocking stub in client

I'm writing a client application in Kotlin where I need to call a GRPC service that has both a future based and a blocking stub.
In case I choose to go with the future option, I will need at some point to do something like a CompletableFuture.get() call, which means I will be blocking anyway.
So, what's the difference between one and the other for this case? Or is it the same?
I will need at some point to do something like a CompletableFuture.get() call, which means I will be blocking anyway
Not necessarily. With a ListenableFuture, CompletableFuture, or other completion-hookable mechanisms, you don't have to block at all. You could register an action to do on completion, or you could wrap them in suspend calls to work with coroutines etc.
Also, even if you did call get() and block, it still allows you to block later than the start of the call, and do other things between the initial call and the get(), which would be concurrent with it:
val future = callSomethingWithFuture()
doStuffConcurrently()
val result = future.get()

What is the use of add_callback_threadsafe() method in pika?

From the description in the pika documentation, I can't quite get what add_callback_threadsafe() method does. It says, "Requests a call to the given function as soon as possible in the context of this connection’s thread". Specifically, which event does this callback get associated to? Since, add_callback_threadsafe() doesn't receive any "event" argument, how does pika know when to invoke that callback?
Also, in the official example, why do we even need to build the partial function and register the callback in the do_work() method? Could we not just call the ack_message() method after the time.sleep() is over?
The reason why the method exists:
How to add multiprocessing to consumer with pika (RabbitMQ) in python
If you use the same rabbit connection/channel with multiple threads/processes then you'll be prone to crashes. If you want to avoid that, you need to use that method.
Could we not just call the ack_message() method after the
time.sleep() is over?
No, you would be calling ack_message from a different thread than the main one, that's not thread safe and prone to crashes. You need to call ack_message from a thread-safe context, i.e., the add_callback_threadsafe().

setConfirmCallback vs setReturnCallback

why setReturnCallback executes before the setConfirmCallback ideally setConfirmCallback callback method should execute before the return callback.
It's not clear what you are asking; if you mean the return callback is called before the confirm callback is called, that's simply the way the broker works.
It is important that it is executed that way. When you use CorrelationData we want to make sure the returned record is added to the CorrelationData before its Future is completed.

Axon & CompletableFuture

I've faced with problems when i try to use CompletableFuture with Axon.
For example:
CompletableFuture future = CompletableFuture.supplyAsync(() -> {
log.info("Start processing target: {}", target.toString());
return new Event();
}, threadPool);
future.thenAcceptAsync(event -> {
log.info("Send Event");
AggregateLifecycle.apply(event);
}, currentExecutor);
in thenAcceptAsync - AggregateLifecycle.apply(event) has unexpected behavior. Some of my #EventSourcingHandler handlers start handling event twice. Does anybody know how to fix it?
I have been reading docs and everything that i got is:
In most cases, the DefaultUnitOfWork will provide you with the
functionality you need. It expects processing to happen within a
single thread.
so, it seems i should use somehow CurrentUnitOfWork.get/set methods but still can't understand Axon API.
You should not apply() events asynchronously. The apply() method will call the aggregate's internal #EventSourcingHandler methods and schedule the event for publication when the unit of work completes (successfully).
The way Axon works with the Unit of Work (which coordinates activity of a single message handler invocation), the apply() method must be invoked in the thread that manages that Unit of Work.
If you want asynchronous publication of Events, use an Event Bus that uses an Async Transport, and use Tracking Processors.

Discard message from nServiceBus mutator

I need to discard a message if a specific header is present.
I tried to implement a IMutateTransportMessages and call DoNotContinueDispatchingCurrentMessageToHandlers() method inside MutateIncoming but the message is dispatched to handlers anyway.
I can discard the message using an handler but I don't like it because I need also to specify the handlers' order.
Any solution?
Thanks,
Federico
I don't think this will be possible from a message mutator. After all, this isn't really the kind of activity a message mutator should be doing - it has nothing to do with changing the structure of the message.
I agree with you that it sounds messy to do this in a handler, because you're right - then you are very dependent upon the handler order.
Discarding a message due to the presence (or absence) of a header is an infrastructure concern, and since you are using NServiceBus V5, the best way to customize the infrastructure is by customizing the message handling pipeline.
Here's the relevant documentation that covers creating a behavior and inserting it into the pipeline but here's the short version:
You need to create a behavior that implements IBehavior<IncomingContext>. All of the behaviors together form a behavior chain that progress to the next step by calling next() - an Action present in the implementation) method.
Within the behavior, check for your header. To stop processing the message, just don't call next() and call context.DoNotInvokeAnyMoreHandlers() instead.
Create a class inheriting RegisterStep which, from its constructor, will define where in the pipeline to insert your behavior. You could register it right before the MutateIncomingTransportMessage step.
Create a class implementing INeedInitialization (note that this could be the same as the RegisterStep class) which calls busConfig.Pipeline.Register<TClassThatInheritsRegisterStep>().
Again, that's the short version. Check out the docs for the full story and an example.
Shameless plug: This process is also described in detail in Learning NServiceBus - Second Edition in Chapter 7, with an example.