In clojure documentation I see that agent use a pool of thread to process data. But I read that (always in documentation) :
The actions of all Agents get interleaved amongst threads in a thread
pool. At any point in time, at most one action for each Agent is being
executed.
Why does an agent have a pool of thread and not a single thread to process the "queue" of sended function ?
Thanks.
An agent does not 'have a pool of threads'. There are two thread pools (for send and send-off actions), to which agent actions get assigned.
This design decision is the optimal choice for CPU-bound tasks, and a best-effort approach for IO-bound tasks.
For the latter case, providing your own pool with send-via will be the optimal choice (assuming you know what you're doing).
Related
The title is pretty much the question. Is there some way to limit the number of concurrent workflows running at any given time?
Some background:
I'm using eventarc to dispatch a workflow once a message has been sent to a pubsub topic. The workflow will be used to start some long-running operation (LRO) but for reasons I won't go into, I don't want more than 3 instances of this workflow running at a given time.
Is there some way to do this? - primarily from some type of configuration rather than using another compute resource.
There is no configuration to limit running processes that specifically targets sessions that are executed by a Workflow enabled for concurrent execution.
The existing process limit applies to all sessions without differentiating between those from non-concurrent or concurrent enabled Workflows.
Synchronization enables users to limit the parallel execution of certain workflows or templates within a workflow without having to restrict others.
Users can create multiple synchronization configurations in the ConfigMap that can be referred to from a workflow or template within a workflow. Alternatively, users can configure a mutex to prevent concurrent execution of templates or workflows using the same mutex.
Refer to this link for more information.
Summarizing your requirements:
Trigger workflow executions with Pub/Sub messages
Execute at most 3 workflow executions concurrently
Queue up waiting Pub/Sub messages
(Unspecified) Do you need messages processed in the order delivered?
There is no out-of-the box capability to achieve this. For fun, below is a solution that doesn't need secondary compute (and therefore is still fully managed).
The key to making this work is likely starting new executions for every message, but waiting in that execution if needed. Workflows does not provide a global concurrency construct, so you'll need to use some external storage, such as Firestore. An algorithm like this could work:
Create a callback
Push the callback into a FIFO queue
Atomically increment a counter (which returns the new value)
If the returned value is <= 3, pop the last callback and call it
Wait on the callback
-- MAIN WORKFLOW HERE --
Atomically decrement the counter
If the returned value is < 3, pop the last callback and call it
To keep things cleaner, you could put the above steps in a the triggered workflow and the main logic in a separate workflow that is called as needed.
I have a Camunda delegate which is supposed to send mails. We want to restrict the parallel executions of tasks so that the mail server is not flooded with too many messages.
Is there any (easy) possibility to restrict that task only to, say, 25 concurrent executions without resorting to Camunda-external synchronization (which is possible but complicated)?
If you make the service task async in the modeler, the camunda jobexecutor will execute the delegate with a managed thread pool, so you will have a maximum of the definied executor threads sending mails. Could already be a solution for your problem.
I want to create a web application were a client calls a REST Webservice. This returns OK-Status for the client (with a link to the result) and creates a new message on an activeMQ Queue. On the listeners side of the activeMQ there should be worker who process the messages.
Iam stucking here with my concept, because i dont really know how to determine the number of workers i need. The workers only have to call web service interfaces, so no high computation power is needed for the worker itself. The most time the worker has to wait for returning results from the called webservice. But one worker can not handle all requests, so if a limit of requests in the queue is exceeded (i dont know the limit yet), another worker should treat the queue.
What is the best practise for doing this job? Should i create one worker per Request and destroying them if the work is done? How to dynamically create workers based on the queue size? Is it better to run these workers all the time or creating them when the queue requiere that?
I think a Topic/Suscriber architecture is not reasonable, because only one worker should care about one request. Lets imagine of 100 Requests per Minute average and 500 requests on high workload.
My intention is to get results fast, so no client have to wait for it answer just because not properly used ressources ...
Thank you
Why don't you figure out the max number of workers you'd realistically be able to support, and then make that number and leave them running forever? I'd use a prefetch of either 0 or 1, to avoid piling up a bunch of messages in one worker's prefetch buffer while the others sit idle. (Prefetch=0 will pull the next message when the current one is finished, whereas prefetch=1 will have a single message sitting "on deck" available to be processed without needing to get it from the network but it means that a consumer might be available to consume a message but can't because it's sitting in another consumer's prefetch buffer waiting for that consumer to be read for it). I'd use prefetch=0 as long as the time to download your messages from the broker isn't unreasonable, since it will spread the workload as evenly as possible.
Then whenever there are messages to be processed, either a worker available to process the next message (so no delay) or all the workers are processing messages (so of course you're going to have to wait because you're at capacity, but as soon as there's a worker available it will take the next message from the queue).
Also, you're right that you want queues (where a message will be consumed by only a single worker) not topics (where a message will be consumed by each worker).
I need to build a thread pool with scheduling priorities: all running threads have the same priority in terms of CPU time and OS priority, but when it takes to pick the next task to complete, the one with the highest priority goes first.
I've decided to try the boost::asio as it has a thread pool that looks good. I've looked over the prioritized handlers example in the asio documentation but I don't like it because it doesn't limit the number of threads, and I have to schedule the tasks manually. What I need is a fixed number of threads that would take tasks from a queue, so I could create the single pool in my application and then add tasks at any time during the application lifetime.
What would be sufficient is getting some notification from the asio::io_service when a task is finished; the handler of that notification could go and find the next task with the highest priority, and post it to the service.
Is that possible?
For object pools, we say that whenever client asks for a resource, we give it from the pool. If I checked out one resource and changed its state and checked it in. What happens on the next request, does the pool let client check out this resource or this resource is invalid for the pool now?
If the object released to the pool became invalid for re-use, the pool would be somewhat pointless. If a class requires initialization, or re-initialization, you could do it in the get() or release() pool methods. If reinitialization requires much more than simple assignments, (eg. a pool of socket objects that must not be re-used for 5 minutes), then you may have to resort to a dedicated pool manager thread that effectively splits the pool into a couple of puddles - those objects available for re-use and those awaiting reinitialization.
Rgds,
Martin
Or, alternatively, you should not return the resource back to the pool until the resource is back to its original state. For example, imagine you have a web server with a listener thread and a pool of 10 worker threads. The listener thread accepts incoming http requests and dispatches them to the worker threads for processing. Worker threads in the pool (not checked-out) are in their "original" state, i.e. idle, or not processing a request. Once the listener thread checks out a worker thread and gives it an http request, the worker thread begins processing the request; in other words, its state is "working". Once it's done processing the request and has sent the http reply to the client, it is "idle" again and goes back into the pool. Thereby, all threads not currently checked out of the pool are always in their original state, "idle".