Repository navigation
Semantical difference between Napi::ThreadSafeFunction and napi_threadsafe_function #594
Description
Activity
Hi @legendecas ,
Yes, this is a good point. It was briefly mentioned here #556 (comment) and discussed in the subsequent napi meeting, and thus spawning #580.
I personally vote for your first solution "Add a caveat section on the doc of Napi::ThreadSafeFunction" because when #580 lands, you can use the tsfn in 1:1 manner. It's just that the "default behavior" is this wrapped thing.
Good to see it's already progressing here.
Yet there is still no constructors for creating
Napi::ThreadSafeFunctionin the manner ofnapi_create_threadsafe_function. Also, the test in #580 just callsnapi_create_threadsafe_functiondirectly to get aside from the problem. Which might not be totalNapiway :DAhhh yes I understand that concern now. Considering that using the current
::Newalways uses thisCallJSwrapper, there may be performance implications.Reacted by Chengzhong WuAfter discussing this with the N-API team, it looks like we may need to remove this functionality from
Napi::ThreadSafeFunctionbecause it incurs too high of a performance penalty. Users can still branch to different callbacks for any given data item based on information they choose to record into such an item, but such logic should not be forced on those who do not need it.Removal per se is not an option for backward compatibility reasons. Thus, we need to figure a way forward so as not to break existing users, while providing as smooth a path away from these shortcomings for those who need it.
After discussing this with the N-API team, it looks like we may need to remove this functionality from
Napi::ThreadSafeFunctionbecause it incurs too high of a performance penalty.Regarding the "performance penalty"... I'm not sure if it's possible to add some type-safety / type-convenience without doing some sort of wrapper around the
napi_create_threadsafe_function call_js_cbparameter, which takes signaturevoid(napi_env env, napi_value js_callback, void *context, void *data)I'm working on the new TSFN API and I'm not sure if a wrap would be allowed here (similar to how we have a
details::FinalizeData<T, Finalizer>wrapper for type convenience) , as this wrap would be done in every tsfn call, which I guess is the performance problem. Hopefully we can discuss in next meetingThis issue is stale because it has been open many days with no activity. It will be closed soon unless the stale label is removed or a comment is made.
I believe this is fixed by #742 @legendecas , @mhdawson , @gabrielschulhof
Napi::ThreadSafeFunctionnow acts as a bridge between the JavaScript function callback and multiple runtime c++ function callbacks. That is to say,Napi::ThreadSafeFunctionhas built a 1:m relation on the JavaScript function and c++ function semantically. See call functions ofNapi::ThreadSafeFunctionand their variants:With these signatures we could provide different c++ functions on each thread safe function call. It might be more convenient to be used. Yet while reviewing
napi_threadsafe_functiondocs, we could find thatnapi_threadsafe_functionhas a 1:1 relation on JavaScript function and c++ function which is built on the creation function signature:Either this behavior was intended or not, this may cause confusion on introducing
Napi::ThreadSafeFunctionto an existing N-API document reader. They may have the impression that a single thread safe function is going to be used for one purpose, and has 1:1 relation on JavaScript function and the c++ function.Possible solutions (might not be the best solutions):
Napi::ThreadSafeFunctionOr it may not be a problem at all.