The Meteor docs state for the assets API:
asyncCallback Function
Optional callback, which is called asynchronously with the error or result after the function is complete. If not provided, the function runs synchronously.
Much of Meteor functions can be used in a synchronous style despite being asynchronously ran.
So is the Assets API blocking synchronous or Fibers synchronous?
It uses fs which is io blocking, with fibers to make it synchronous:
https://github.com/meteor/meteor/blob/19080bd53de3e0954e17914410bcf3fa0fead9c8/tools/server/boot.js#L189
So its 'fibers blocking', where you can use this.unblock() in a method to create a new fiber if the current one is being blocked.
Related
I used zookpeer asynchronous api with c client to monitor my cluster, such as zwget. I found some confusing bugs when my app is running for a while (zookeeper cluster was unstable and a new leader may be selected in this time).
The problem is:
The Watcher of the asynchronous api is called first before completion callback.
And I have searched zookeeper offical docs,so the following passage hints that it is possible for the asynchronous API to notify Watcher before the completion callback, am I right?
Synchronous calls may not return in the correct order. For example, assume a client does the following processing: issues an asynchronous read of node /a with watch set to true, and then in the completion callback of the read it does a synchronous read of /a. (Maybe not good practice, but not illegal either, and it makes for a simple example.)
Note that if there is a change to /a between the asynchronous read and the synchronous read, the client library will receive the watch event saying /a changed before the response for the synchronous read, but because the completion callback is blocking the event queue, the synchronous read will return with the new value of /a before the watch event is processed.
I have read tutorial and googled for this question, but still have some confuse. here is my understand about their difference, but I'm not sure whether it's right.
callback is also an synchronous style
synchronous and callback grpc cpp itself manage request and response queue and thread model, but asynchronous let user provide a thread management, am I right?
sync and callback sytle is not multiple threaded, am I right?
synchronous and callback have same performance, but asynchronous style can archive very high performance?
I have the following problem:
I'm trying to call sync closure from async function, but sync closure has to later call another async function.
I cannot make async closure, because they are unstable at the moment:
error[E0658]: async closures are unstable
so I have to do it this way somehow.
I found a couple of questions related to the problem, such as this, but when I tried to implement it, im receiving the following error:
Cannot start a runtime from within a runtime.
This happens because a function (like `block_on`)
attempted to block the current thread while the
thread is being used to drive asynchronous tasks.'
here is playground link which hopefully can show what I'm having problem with.
I'm using tokio as stated in the title.
As the error message states, Tokio doesn't allow you to have nested runtimes.
There's a section in the documentation for Tokio's Mutex which states the following (link):
[It] is ok and often preferred to use the ordinary Mutex from the standard library in asynchronous code. [...] the feature that the async mutex offers over the blocking mutex is that it is possible to keep the mutex locked across an .await point, which is rarely necessary for data.
Additionally, from Tokio's mini-Redis example:
A Tokio mutex is mostly intended to be used when locks need to be held
across .await yield points. All other cases are usually best
served by a std mutex. If the critical section does not include any
async operations but is long (CPU intensive or performing blocking
operations), then the entire operation, including waiting for the mutex,
is considered a "blocking" operation and tokio::task::spawn_blocking
should be used.
If the Mutex is the only async thing you need in your synchronous call, it's most likely better to make it a blocking Mutex. In that case, you can lock it from async code by first calling try_lock(), and, if that fails, attempting to lock it in a blocking context via spawn_blocking.
I am writing a service using Ktor and Exposed ORM which apparently isn't async. I am coming from the Python world and back there using a blocking ORM with a async IO library is a sin as it may block all users in thread.
Does the same rule apply in Kotlin? Am I creating a bad architecture?
Exposed uses thread local storage to keep transaction instance accessible to implementation and avoid passing it along with every function call. Since transaction DSL function is executing synchronously and do not release a thread to be reusable by ktor for other calls there shouldn't be any issues with using them together.
There is coroutine support in Exposed.
Please read the documentation:
https://github.com/JetBrains/Exposed/wiki/Transactions#working-with-coroutines
Here's a blogpost that shows how to use them together:
https://ryanharrison.co.uk/2018/04/14/kotlin-ktor-exposed-starter.html
I have also successfully done so myself in a test-project but I'm not yet at a point where I'm ready to share the code.
In short, you can use Kotlin coroutines in such a way that you do the database transaction on a thread so they do not block KTOR's request handling loop.
If using the right coroutine dispatcher, then this should not give any problem with the threadlocal transaction context.
Meteor's documentation states:
In Meteor, your server code runs in a single thread per request, not in the asynchronous callback style typical of Node
Do they actually mean?
A) the server is running multiple threads in parallel (which seems unusual within the Node.js ecosystem)
or
B) There is still only a single thread within an evented server and each request is processed sequentially, at least until it makes calls to resources outside the server - like the datastore, at which point the server itself is handling the callbacks while it processes with other requests, so you don't have to write/administer the callbacks yourself.
Brad, your B is correct.
Meteor uses fibers internally. As you said, there's only one thread inside an evented server, but when you do (eg) a database read, Fibers yields and control quickly gets back to the event loop. So your code looks like:
doc = MyCollection.findOne(id);
(with a hidden "yield to the event loop, come back when the doc is here") rather than
MyCollection.findOne(id, function (err, doc) {
if (err)
handle(err);
process(doc);
});
Error handling in the fiber version also just uses standard JavaScript exceptions instead of needing to check an argument every time.
I think this leads to an easier style of code to read for business logic which wants to take a bunch of actions which depend on each other in series. However, most of Meteor's synchronous APIs optionally take callbacks and become asynchronous, if you'd like to use the async style.