Asynchronous vs Synchronous Callbacks in Plotly Dash for Python - plotly-dash

I am designing an app that will have multiple callbacks, each querying different tables of a SQL db.
As I am designingg, it will be helpful to understand if the callbacks will update (query the db) synchronously or asynchronously.
Per the docs, for advanced callbacks:
Whether or not these requests are executed in a synchronous or
asynchronous manner depends on the specific setup of the Dash back-end
server. If it is running in a multi-threaded environment, then all of
the callbacks can be executed simultaneously, and they will return
values based on their speed of execution. In a single-threaded
environment however, callbacks will be executed one at a time in the
order they are received by the server.
Given that this is in Python, would that mean by default that I am running a “single-thread environment?”
If asynchronous the the only option, is there a way to use a package like ‘asyncio’ to at least speed up the total time it takes for all callbacks to load?
thank you!!

Related

Is it possible to run functions from asynchronous libraries like asyncpg in Beam ParDo?

We are using pg8000 as the driver for inserting records into our Cloud SQL Postgres instance. Our Beam code is in Python and uses the library sqlalchemy to interact with the database. We find pg8000 too slow and tested asyncpg instead locally (no Beam code) with promising results. We used this as a reference in using asyncpg:
https://github.com/GoogleCloudPlatform/cloud-sql-python-connector/blob/main/README.md
Can we use asynchronous functions like asyncpg in establishing DB connection within a Beam ParDo? How do we structure the PTransform's functions like setup (establishing an async connection), start_bundle (start the transaction), process (perform SQL operation), finish_bundle (commit/rollback the transaction), tear_down (close the connection)?
Yes, it is possible to use asynchronous functions if you are careful. Here is what you have to be careful of:
Beam objects passed to your DoFn are generally not intended for concurrent use, so you should not pass Beam objects to the concurrent functions. Instead, you should just use the functions to do generic processing and keep all the Beam-specific logic on the main thread.
You need to wait for all the asynchronous tasks to finish in finishBundle, so that all processing is done before the bundle is committed as "done".

Will my server be able to run only one client if its a single-threaded process. If yes, why?

I have googled decent enough to understand threads and processes. One thing I am confused is about single-threaded process.
The scenario is the Server-Client application process where each client is treated as a single process in the server that is single-threaded.
Some blogs are saying that single-threaded program will not be able to handle multiple clients at a time ie., it can start one process and only after finishing it, another process can be started. But some blogs saying its possible.
According to my understanding, in a single-core processor system, if its programmed for multi-tasking, depending on the time-slice allocated for each processes, more than one process can be concurrently handled. In multi-processor system also, more than one client process can be handled in parallel.
Is it just the web servers that does not handle more than one process at a time because it is iterative server? If its anyother concurrent server, will it be handling more than one process, without waiting for each process to get completed to handle the next one..?
As I am confused by many different explanations in different blogs, I am expecting a very accurate answer just for the above mentioned scenario, in either a single-processor with multi-tasking environment (or) a multi-processor environment. Also, would like to know if there are any benefits of using a single-threaded process over a process without any threads.
Sorry If my understanding is wrong. Kindly respond.
Thanks in advance..
If your server does this:
while(true)
listen()
accept()
read()
process()
write()
close()
And each of the calls to accept, read, process, write and close are single-threaded, then the server cannot listen for new requests again until those calls complete. The requests might queue up or simply get dropped if the server is not listening for them. If accept/read/process/write/close take a long time compared to listen(), then your server will not be available to service requests frequently. Moreoever, if some requests take 100 seconds and some requests take 1 second, and a lot of that time is blocking on I/O to e.g. a database or a web service, then you're spending most of your time in the server doing nothing. Here's the alternative:
while(true)
listen()
start new thread()
accept()
read()
process()
write()
close()
Now all you're doing synchronously is kicking off the new thread to handle the incoming request, and then immediately beginning to listen again. The OS will handle scheduling the threads and if some of them end up waiting a long time for some I/O to occur, your server can still process the fast requests in the meantime.

Azure - Trigger which copies multible blobs

I am currently working on a ServiceBus trigger (using C#) which copies and moves related blobs to another blob storage and Azure Data Lake. After copying, the function has to emit a notification to trigger further processing tasks. Therefore, I need to know, when the copy/move task has been finished.
My first approach was to use a Azure Function which copies all these files. However, Azure Functions have a processing time limit of 10 minutes (when manually set) and therefore it seems to be not the right solution. I was considering calling azCopy or StartCopyAsync() to perform an asynchronous copy, but as far as I understand, the processing time of the function will be as long as azCopy takes. To solve the time limit problem, I could use WebJobs instead, but there are also other technologies like Logic Apps, Durable Azure functions, Batch jobs, etc. which makes me confused about choosing the right technology for this problem. The function won't be called every second but might copy large data. Does anybody have an idea?
I just found out that Azure Functions only have a time limit when using consumption plan. If there is no better solution for copy blob tasks, I'll go for Azure Functions.

Push Data onto Queue vs Pull Data by Workers

I am building a web site backend that involves a client submitting a request to perform some expensive (in time) operation. The expensive operation also involves gathering some set of information for it to complete.
The work that the client submits can be fully described by a uuid. I am hoping to use a service oriented architecture (SOA) (i.e. multiple micro-services).
The client communicates with the backend using RESTful communication over HTTP. I plan to use a queue that the workers performing the expensive operation can poll for work. The queue has persistence and offers decent reliability semantics.
One consideration is whether I gather all of the data needed for the expensive operation upstream and then enqueue all of that data or whether I just enqueue the uuid and let the worker fetch the data.
Here are diagrams of the two architectures under consideration:
Push-based (i.e. gather data upstream):
Pull-based (i.e. worker gathers the data):
Some things that I have thought of:
In the push-based case, I would be likely be blocking while I gathered the needed data so the client's HTTP request would not be responded to until the data is gathered and then enqueued. From a UI standpoint, the request would be pending until the response comes back.
In the pull based scenario, only the worker needs to know what data is required for the work. That means I can have multiple types of clients talking to various backends. If the data needs change I update just the workers and not each of the upstream services.
Any thing else that I am missing here?
Another benefit of the pull based approach is that you don't have to worry about the data getting stale in the queue.
I think you already pretty much explained that the second (pull-based) approach is better.
If a user's request should anyway be processed asynchronously, why wait for the data to be gathered and then return a response. You need just to queue a work item and return HTTP response.
Passing data via queue is not a good option. If you get the data upstream, you will have to pass it somehow other than via queue to the worker (usually BLOB storage). That is additional work that is not really needed in your case.
I would recommend Cadence Workflow instead of queues as it supports long running operations and state management out of the box.
Cadence offers a lot of other advantages over using queues for task processing.
Built it exponential retries with unlimited expiration interval
Failure handling. For example it allows to execute a task that notifies another service if both updates couldn't succeed during a configured interval.
Support for long running heartbeating operations
Ability to implement complex task dependencies. For example to implement chaining of calls or compensation logic in case of unrecoverble failures (SAGA)
Gives complete visibility into current state of the update. For example when using queues all you know if there are some messages in a queue and you need additional DB to track the overall progress. With Cadence every event is recorded.
Ability to cancel an update in flight.
See the presentation that goes over Cadence programming model.

Accessing MySQL database from Delphi asynchronously

How to access MySQL database from Delphi asynchronously?
Thread that executes select statement should not be blocked. Creating background threads for each active select statement is not a solution too, because on heavy loaded system this would create to many threads and would lead to performance problems.
IOCP (i/o completion ports) is exactly what I need. But I don't know how to use this technology with MySQL from Delphi.
If you have some kind of application where it actually makes sense to execute queries asynchronously, then do it. Let the server deal with the concurrency issue. You can easily configure the server.
For example, take a look at innodb_thread_concurrency and max_connections.