Psycopg3 supports async connections and async cursors. I have multiple writer tasks writing to a database. Should I pass each of those tasks the same AsyncConnection? If not, should I pass them the same AsyncCursor? Or should I make a new connection in each of the functions?
eg: below, would I send aconn to each of my tasks? Or cur? Or should this code be in each of the tasks?
async with await psycopg.AsyncConnection.connect() as aconn:
async with aconn.cursor() as cur:
await cur.execute(...)
All of the example code I could find had only one task being created. Thanks!
Related
I am new in flutter. I need to call 5 API network calls in a single screen. It is taking very long time while i am using Async/await. How can we execute it on separate threads parallelly using isolate or anything else like it?
You may use isolate for this purpose isolate is a sort of multi threading in dart. Isolate creates a new thread and execute operation on the new thread so that the load will be distributed. You cannot send variables as a data back and forth but use port to send messages.
Here is a simple example of isolate with an API call and sending data back to the main thread using port.
First lets create a function which will be the entrypoint of isolate:
static entryPoint(SendPort sendPort)async{
var response = await http.get('https://www.thecocktaildb.com/api/json/v1/1/search.php?s=margarita');
sendPort.send(response.body); //sending data back to main thread's function
}
Now lets create isolate:
static void callApi()async{
var recievePort = new ReceivePort(); //creating new port to listen data
await Isolate.spawn(entryPoint, recievePort.sendPort);//spawing/creating new thread as isolates.
recievePort.listen((message) { //listening data from isolate
print(message);
});
}
You can use dio package and call multiple concurrent API requests, do check the documentation:
Package: https://pub.dev/packages/dio
You can use Future.wait()
Here is the answer with an example
I am current writing a WebSocket client. There are a few functions that I need to happen sequentially.
currently I do it in this way
Connect to server
Then set up a listener.
Add Conditional statement to listener.(To check if response id's match request ids)
send request One with id
if response id matches request One Id then process request
send request Two
repeat
This makes sequential actions look something like this
_channel.stream.listen((response) {
if(response.id == requestOne.id) {
handleRequestOneResponse(response);
}
if (response.id == requestTwo.id){
handleRequestTwoResponse(response);
}
...
});
sendActionOneRequest();
handleRequestOneResponse() {
// Some processing
sendActionTwoRequest();
}
handleRequestTwoResponse() {
// some processing
sendActionThreeRequest();
}
What I want to do is
Set up an async function
Send the request to the WebSocket server.
Pause the execution of the async function.
wait until a matching response comes from the server
complete the async function.
This would allow me to write a series of actions like
await actionOne();
await actionTwo();
await actionThree();
I'm thinking I can set up and destroy a stream listener in each action function but I don't know how to wait for a specific response before exiting.
On the other hand I think I can even use the existing listener on the outside, but I still can't figure out to wait till a specific response comes in before moving forward.
As it is I have to jump through every function to find out what comes after the other and there are more than 5 requests that have to be sent sequentially.
So, I am doing a course on web development and I'm doing mongoDB middleware stuff and I noticed the teacher was using an async function instead of a simple one and I really don't see the difference, I mean I understand the concept but I don't see how would it change the code's behavior.
personSchema.pre("save", async function(){
console.log("Saving...");
});
personSchema.post("save", async function(){
console.log("SAVED!");
});
I am working on a small flutter app where I use a native library for some computation. The communication is two-way between dart and java (on android) and uses methodChannels for this.
I call await in_channel.invokeMethod("someJavaMethod") from dart to start the computation. This triggers an init of the native library from Java. The result from this init is coming back as an async JNI call which then triggers out_channel.invokeMethod("someDartMethod").
My plan was to bind the out_channel to a local dart broadcast stream such that I could invoke someJavaMethod and then just await myMethodStream.where((m) => m.method == "someDartMethod")...
Problem is that the "someDartMethod" can come before the "someJavaMethod" call invocation has returned.
combined code example of what I have:
static const MethodChannel _channel_in = const
MethodChannel('native_lib_wrapper_out');
static const MethodChannel _channel_out = const
MethodChannel('native_lib_wrapper_in');
final StreamController<MethodCall> _methodStreamController = new
StreamController.broadcast();
NativeLibWrapper._() {
_channel_in.setMethodCallHandler((MethodCall call) {
_methodStreamController.add(call);
return;
});
}
Future<Map<dynamic,dynamic>> initLib(String id, String filePath)
async {
Map<dynamic,dynamic> ret;
ret = await _channel_out.invokeMethod("initLib", <String,
dynamic> { // data to be passed to the function
'id': id,
'filePath': filePath,
});
print('initLib - invokeMethod done. wait for stream');
if(ret["status"] == 0) {
await NativeLibWrapper.instance._methodStream
.where((m) => m.method == "libInitEnded")
.map((m){
var args = m.arguments;
ret = args;
}).first;
}
return ret;
}
I would have expected the code to get the method call libInitEnded on my stream and then it should return after that point but it continuously hangs in the await on the stream and from the logs it looks like the libInitEnded is called before the print in the middle.
So is there a better way to structure this? it will not be the only methods going back and forth so I hope to get a good stable solution for this.
One channel
You should only need one channel. No need for in and out channels. Both ends may invoke operations on the other over the one channel.
There's only one UI thread
When you call from Dart to Native, the native method is handled by the native UI thread. Unless you are using a thread pool, that means that Dart to Native methods are handled in order. There's no point in not awaiting the answer of every native method. Or, in other words, there's no point in launching two native methods at the same time, since they will be executed consecutively by the single native thread. (Note that you should not perform time-consuming operations on the native thread, as this will interfere with other things it does like gesture detection.) Every Dart to native method should return its result.
Using a thread pool
If the single thread / single method call at a time is unacceptable, consider a thread pool at the native end. Now you can have multiple methods in flight, since there are multiple threads of execution. Now you should design your call/response like you might for communication with a server over a socket. The client gives each request an "invoke id". Each method simply returns a boolean that the request was queued. On completion of the request, the other end invokes the 'done' method, passing the original id and the result. The caller can then match up the response id with the request id and handle the response appropriately (and cancel any timer started to detect timeout). Note that responses can then arrive in any order, but are matched with their request by id.
On Android, you must invoke native to Dart methods on the UIThread. If you are calling the 'done' method from a worker thread you need to post a Runnable lambda to the main looper.
I have a Protractor test suite that has been partially converted to use async / await instead of the control flow, but I need to call some async helper functions from old-style tests that still need the control flow. How can I make sure the async Promise executes in the right order?
Async functions return a Promise. Use browser.controlFlow().wait(Promise) to explicitly add these to the control flow.
it('is a test', function () {
let flow = browser.controlFlow();
ordinaryHelper();
flow.wait(asyncHelper());
});