Created
October 15, 2019 21:33
-
-
Save deepal/23ddf2414cadc777c05adee6ad9f3c67 to your computer and use it in GitHub Desktop.
Factory method to create worker instances
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void Worker::New(const FunctionCallbackInfo<Value>& args) { | |
Environment* env = Environment::GetCurrent(args); | |
CHECK(args.IsConstructCall()); | |
if (env->isolate_data()->platform() == nullptr) { | |
THROW_ERR_MISSING_PLATFORM_FOR_WORKER(env); | |
return; | |
} | |
std::string url; | |
std::shared_ptr<PerIsolateOptions> per_isolate_opts = nullptr; | |
std::vector<std::string> exec_argv_out; | |
bool has_explicit_exec_argv = false; | |
CHECK_EQ(args.Length(), 2); | |
// Argument might be a string or URL | |
if (!args[0]->IsNullOrUndefined()) { | |
Utf8Value value( | |
args.GetIsolate(), | |
args[0]->ToString(env->context()).FromMaybe(Local<String>())); | |
url.append(value.out(), value.length()); | |
std::cout << "node_worker.cc[Worker::New()] Creating new worker for " << url << "\n"; | |
} | |
if (args[1]->IsArray()) { | |
// Check this out later | |
Local<Array> array = args[1].As<Array>(); | |
// The first argument is reserved for program name, but we don't need it | |
// in workers. | |
has_explicit_exec_argv = true; | |
std::vector<std::string> exec_argv = {""}; | |
uint32_t length = array->Length(); | |
for (uint32_t i = 0; i < length; i++) { | |
Local<Value> arg; | |
if (!array->Get(env->context(), i).ToLocal(&arg)) { | |
return; | |
} | |
MaybeLocal<String> arg_v8_string = | |
arg->ToString(env->context()); | |
if (arg_v8_string.IsEmpty()) { | |
return; | |
} | |
Utf8Value arg_utf8_value( | |
args.GetIsolate(), | |
arg_v8_string.FromMaybe(Local<String>())); | |
std::string arg_string(arg_utf8_value.out(), arg_utf8_value.length()); | |
exec_argv.push_back(arg_string); | |
} | |
std::vector<std::string> invalid_args{}; | |
std::vector<std::string> errors{}; | |
per_isolate_opts.reset(new PerIsolateOptions()); | |
// Using invalid_args as the v8_args argument as it stores unknown | |
// options for the per isolate parser. | |
options_parser::Parse( | |
&exec_argv, | |
&exec_argv_out, | |
&invalid_args, | |
per_isolate_opts.get(), | |
kDisallowedInEnvironment, | |
&errors); | |
// The first argument is program name. | |
invalid_args.erase(invalid_args.begin()); | |
if (errors.size() > 0 || invalid_args.size() > 0) { | |
Local<Value> error; | |
if (!ToV8Value(env->context(), | |
errors.size() > 0 ? errors : invalid_args) | |
.ToLocal(&error)) { | |
return; | |
} | |
Local<String> key = | |
FIXED_ONE_BYTE_STRING(env->isolate(), "invalidExecArgv"); | |
// Ignore the return value of Set() because exceptions bubble up to JS | |
// when we return anyway. | |
USE(args.This()->Set(env->context(), key, error)); | |
return; | |
} | |
} | |
if (!has_explicit_exec_argv) | |
exec_argv_out = env->exec_argv(); | |
new Worker(env, args.This(), url, per_isolate_opts, std::move(exec_argv_out)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment