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

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

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()

Problems with OpenRTI callbacks

How in the OpenRTI to make the rti send callbacks? For example, reserve a name with the reserveObjectInstanceName
_rtiAmbassador->reserveObjectInstanceName(name);
Errors:
terminate called after throwing an instance of
'rti1516e::ObjectInstanceNameNotReserved'
If you are using the HLA 1516e API (as opposed to HLA 1516 or HLA 1.3) when you make a call to connect you can specify a CallbackModel which is either SYNCHRONOUS or ASYNCHRONOUS. In a synchronous callback model, the federate has to call the method evokeCallback in order to trigger the RTI to send whatever is queued up. In asynchronous, the callbacks are sent automatically.
What you should do in this instance is have something like this:
_rtiAmbassador->reserveObjectInstanceName(std::wstring(L"MyObject"));
_rtiAmbassador->evokeMultipleCallbacks();
MyFederateAmbassador::objectInstanceNameReservationSucceeded(std::wstring const & name){
_rtiAmbassador->registerObjectInstance(handle, std::wstring(L"MyObject"));
}
After each call to RTI, to get a callback, you need to call
evokeCallback()

In hiredis async, can event_base_dispatch(base) be called from a different thread?

This query is with respect to the example provided in hiredis
Can event_base_dispatch(base) be called from a different thread by creating pthread_create()?
It is a fact that event_base_dispatch() is a loop and it is a blocking call. My idea here is to send all my redis command from the parent thread by invoking redisAsyncCommand(), event base will be run in the other thread.
you need to use add enable_thread_safe_windows function before you create a event base.

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.

Timing and repeating thread execution in Objective-C

I'm wondering if I'm able to time a thread to be executed repeatedly (like when using the scheduledTimerWithTimeInterval method in NSTimer).. I have a view controller, where there is a method I want it to be executed either manually (by clicking a button), or automatically (by timing the method execution). The problem is that, this method will connect with a remote server, and it will update the result on the view, so I don't want it to block the main thread (the view controller thread).
I don't know what to use, so if there's anyone knows how, please let me know :)
Thanks in advance..
It sounds like you might be using an NSURLConnection, and if that's the case, then as joshpaul noted, it will act asynchronously by default. That is to say, when you start the connection, the NSURLConnection object will create a new thread, do its work on that thread, and return results to you on the original thread via the delegate methods, cleaning up the second thread afterwards. This means that the original thread, main or not, will not be blocked while the connection does its work. All you have to do, then, is have your timer's action create and run the connection.
In other cases, you have a couple of options. It's easy enough to set up a timer method that will call another method to be performed in the background:
- (void)periodicMethodTimerFire:(NSTimer *)tim {
[self performSelectorInBackground:#selector(myPeriodicMethod:)
withObject:myPeriodicArgument];
}
This can make it difficult to get results back from the other thread (because you need to pass a reference to the original thread to the method). However, since you seem to be on the main thread to begin with, you can use performSelectorOnMainThread:withObject:waitUntilDone: passing NO for the wait argument to get back.
The more complicated option is to set up your own background thread with a timer running on it, but I'd be surprised if that was really necessary.
If you're using NSURLConnection, it's asynchronous. That'll likely work for your needs.