Can someone give me some guidance on how to use OmniThreadLibrary to perform a "queued" task. Could be anything, but in this question let me use the example of sending 100 emails. I want to only be using 3 threads at a time.
How do I queue the sending of emails?
How do I get notified when 1 thread is finished and ready to receive the next email/task?
How do I get the result of the email send? (i.e. OK, or an error occurred).
I have seen some very short examples of using OTL, but I need something a bit more comprehensive, to understand how to perform the above.
Can someone explain how to do the above or point me to an example that covers something similar.
Thanks
Related
I am running a Rust app with Tokio in prod. In the last version i had a bug, and some requests caused my code to go into an infinite loop.
What happened is while the task that got into the loop was stuck, all the other task continue to work well and processing requests, that happened until the number of stalling tasks was high enough to cause my program to be unresponsive.
My problem is took a lot of time to our monitoring systems to identify that something go wrong. For example, the task that answer to Kubernetes' health check works well and I wasn't able to identify that I have stalled tasks in my system.
So my question is if there's a way to identify and alert in such cases?
If i could find way to define timeout on task, and if it's not return to the scheduler after X seconds/millis to mark the task as stalled, that will be a good enough solution for me.
Using tracing might be an option here: following issue 2655 every tokio task should have a span. Alongside tracing-futures this means you should get a tracing event every time a task is entered or suspended (see this example), by adding the relevant data (e.g. task id / request id / ...) you should then be able to feed this information to an analysis tool in order to know:
that a task is blocked (was resumed then never suspended again)
if you add your own spans, that a "userland" span was never exited / closed, which might mean it's stuck in a non-blocking loop (which is also an issue though somewhat less so)
I think that's about the extent of it: as noted by issue 2510, tokio doesn't yet use the tracing information it generates and so provide no "built-in" introspection facilities.
I am creating a chatbot which have an intent with a payment link. So on trigger of this intent, I made call from webhook fulfillment to third party api which takes approx 20secs to respond. But in this period of time my response is timed out as it is limited to 5 sec from google.
Can you please suggest what approach should I follow. I just want to wait for approx 20 sec to respond.
Thanks.
one option is to keep the conversation alive using events (generated by the webhook) which trigger dedicated intents.
When a payment must be performed the webhook starts a background process to deal with the 3rd party payment API, and sleep for 4-5 sec, after that generates an event (setFollowupEvent PAYMENT_IN_PROGRESS). This event is associated to a DialogFlow Intent which fires as soon as the event is sent back to the platform.
At this point you have another incoming webhook call: check status of the payment, if it is still in progress (likely after 5 sec) then sleep 4-5 sec and send another event (setFollowupEvent PAYMENT_IN_PROGRESS_2) which produces the same workflow.
There are so many times you can do this (I think a max of 3), so you need to cater for the fact that the payment does not terminate in time (fallback scenario).
A smart option could be to keep engaging the user with the conversation, not always easy, depending on what your chatbot is about.
Hope it helps.
The short answer is that you can't.
The longer answer is that you need to think about this as a conversation. If you asked someone a question, and didn't get any response from them for 20 seconds - that would be pretty uncomfortable, wouldn't it?
Instead, we have come up with ways to compensate for that silence. In a physical conversation, people may engage with you and ask you questions to fill the time. If you're on the phone, they may play hold music. Or we may end the conversation for now and tell them later when there is a result.
When building an Action, we have similar parallels that may work better or worse based on our exact needs.
Engaging in conversation
One approach is that when we get the request from the user, we do two things:
Start a task that will execute the query and save the results in a separate "answer database", indexed against the user, a session ID, or some other temporary id we can generate and use later.
While the query is running, we reply to the user saying we're working on it, and asking them another question.
Then, when they reply with their answer to this other question, we can check if we have an answer for them in the database. If we do, we'll reply with it. If not, we'll repeat step 2 until we do.
This approach works well if we either have other questions to ask, or if we're in a good place to "make small talk". Picture booking an airline reservation - while we look up flights, we may want to ask if they prefer window or aisle seats (Which we'd need to ask later) or make small talk by asking if they're traveling for business or leisure.
Using "hold music"
A variant of this allows us to play some hold music while we're processing the answer.
Instead of asking a question in step 2 above, we reply with a Media Response that plays 20 seconds or so of music. When the music completes, our fulfillment webhook will be sent a MEDIA_STATUS event and we can either return the information from the answer database, or say we're still working on it and play more music.
This is less conversational, but may work better if we don't actually have anything to say in the meantime.
Sending a notification
If the response may take a very long time, then it may just be best to let them do other things and to send a notification or a text or email when you have a result. These cases, however, require the user to have registered with you in some way and are probably more appropriate if you have a long-standing relationship with the user.
Summary
You should be returning results as quickly as you can to keep it feeling like a conversation. When you can't, consider other means, just like how we would consider what it would be like if we were talking to another person.
I have a few specific questions related to service bus, that I wanted to get more insights into. I have read a lot of blogs, and a lot of documentation in regards to Service Bus (SB), and have implemented a solution that works using it. The questions that I am going to ask, how not been answered, or have been answered in an unclear way, so that's why I want to get more into specifics. So here they go:
1) Just wanted to get more detail in regards to "OnMessage" function for a ServiceBus queue. From what I understand it's not a typical while()/Receive() loop with a Sleep() interval, but in fact more of a "push" based approach, according to the documentation and my testing. So my question is if I set "AutoRenewTimeout" to 1 minute, then what happens to the thread that is waiting for a message to be received for that 1 minute before issuing a new Receive() operation..Does it sleep & wait for a message from ServiceBus to get "pushed" to it? or is it more of an asynchronous approach here where a thread is released back to the pool and only grabbed again to do work when a message arrives say 47 seconds into the 1 minute AutoRenewTimeout window that I set? (No, I am not talking about "OnMessageAsync" here) I guess this question touches the internals of WCF on which SB is implemented.
2) In regards to question 1), what would the significance be of setting "AutoRenewTimeout" to 5 minutes, or 10 minutes, or 60 minutes, besides the obvious cost of Receive() operation that would be triggered at those intervals? I guess from a customer's perspective, the less frequently I trigger receive operations the more cost effective it is for me, but as far as "waiting for the message" during this period from a service bus perspective / application perspective, what is the recommened "AutoRenewTimeout" perioud? Is SB more prone to drop a connection if "AutoRenewTimeout" is set to 1 hour vs. 1 minute? are more resources / thread usages being used up when the "AutoRenewTimeout" is longer? I wasn't able to find any clear answers to this on any post/blog/documentation that I've read.
3) I have a Topic/Subscription application deployed on each server that both sends/receive messages to/from a topic. Now, I don't want each client(server) to receive the messages that it itself sent out, I only want to receive the messages that other servers(clients) sent out. I was able to implement a solution using a SqlFilter(), but I was wondering if there's any other/better way of doing this? While talking about SqlFilters(), what is the performance impact, if any, on the speed of message delivery between subscription clients when using a simple comparison SqlFilter()? (I guess I could benchmark and see for myself, but I am just curious to take a peek at the internals)
4) In regards to PeekAndLock mode on message receiver, if in a hypothetical scenario, where a message is being marked completed at the time it is received on SB end, someone was able to physically cut the wire between SB end and the application VM, then that message would be lost forever, because the application would not receive it, yet the SB would have checked it off as being Completed. Is my understanding correct, that in PeekAndLock mode the message is being marked off as completed without the application end having an sure guarantee of ever receiving it?
5) In regards to deleting a subscription for a topic, that lets say has 100 messages in it that were never received, would that count as 1 operation, or as 101 operations?
Thank you for your time and effort in taking to read this. I would be glad to clarify any point if necessary. Abhishek, you seem to be one of the architects of SB, so if you see this post, I would really appreciate if you would drop a few comments:)
Thank you!
We're porting Isis2 (isis2.codeplex.com) to make better use of Infiniband verbs and have our code running. However, IB is oriented around an asynchronous receive model in which you post a bunch of receive buffers and then, as receives complete, you process the received data.
Polling is slow: if I use a blocking wait for, say, 2ms, I might delay as long as 2ms before seeing the IB data. So that's a solution, but a poor one. What I really want is a way to wait until an IB completion record is finalized and then to have my thread wake up instantly (on Windows this is easy... on Linux it isn't as natural). Does anyone know how one does this? When using Verbs, there isn't any IB file descriptor, so obviously I can't use select()
Never mind; we just realized that they offer a method (ibv_reg_notify_cq) for this. We'll try that. Not the world's best documented API...
I've recently been investigating and playing around with linux message queues and have come across something that I don't quite understand why it happens!
If we have two programs running that are both using msgrcv() in an infinite for loop to check for messages and then send two messages, the first program running will receive the 1st message, and the second program the 2nd message? If you keep sending messages it then alternates between each receiver.
Obviously, I understand that as soon as one program has read the message it is removed from the queue but who/how is it decided who will receive the message if they are all infinitely checking?
Any help would be appreciated!
The short answer is that the kernel decides.
The long answer is that this is handled by the do_msgrcv() call within the Linux kernel. If there is no message available, the caller gets put on a queue until a message is available. It's not guaranteed to go back and forth like you describe, since it all depends on the timing of each msgrcv() call, but in your case, it will probably behave that way virtually all of the time.