k2hdkc 1.0.13 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -27,280 +27,297 @@
27
27
  //---------------------------------------------------------
28
28
  // InitWorker class
29
29
  //
30
- // Constructor: constructor(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, bool is_auto_rejoin, bool is_nogiveup_rejoin)
30
+ // Constructor: constructor(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin)
31
31
  // Callback function: function(string error)
32
32
  //
33
33
  //---------------------------------------------------------
34
- class InitWorker : public Nan::AsyncWorker
34
+ class InitWorker : public Napi::AsyncWorker
35
35
  {
36
36
  public:
37
- InitWorker(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, const char* inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin) :
38
- Nan::AsyncWorker(callback), pslaveobj(pobj),
39
- is_set_conf(NULL != configuration), conf(configuration ? configuration : ""), ctlport(control_port), cuk(inputcuk ? inputcuk : ""), auto_rejoin(is_auto_rejoin), no_giveup_rejoin(is_nogiveup_rejoin)
40
- {}
41
- ~InitWorker() {}
37
+ InitWorker(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin) :
38
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)),
39
+ _slaveobj(slaveobj), _conf(configuration), _ctlport(control_port), _cuk(inputcuk), _auto_rejoin(is_auto_rejoin), _no_giveup_rejoin(is_nogiveup_rejoin)
40
+ {
41
+ _callbackRef.Ref();
42
+ }
42
43
 
43
- void Execute()
44
+ ~InitWorker() override
44
45
  {
45
- if(!pslaveobj){
46
- this->SetErrorMessage("No object is associated to async worker");
47
- return;
46
+ if(_callbackRef){
47
+ _callbackRef.Unref();
48
+ _callbackRef.Reset();
48
49
  }
49
- if(!is_set_conf){
50
- this->SetErrorMessage("No configuration is associated to async worker");
50
+ }
51
+
52
+ // Run on worker thread
53
+ void Execute() override
54
+ {
55
+ if(_conf.empty()){
56
+ SetError("No configuration is associated to async worker");
51
57
  return;
52
58
  }
53
59
 
54
60
  // build permanent connection object
55
- if(pslaveobj->Initialize(conf.c_str(), ctlport, (cuk.empty() ? NULL : cuk.c_str()), auto_rejoin)){
56
- if(!pslaveobj->Open(no_giveup_rejoin)){
61
+ if(_slaveobj.Initialize(_conf.c_str(), _ctlport, (_cuk.empty() ? NULL : _cuk.c_str()), _auto_rejoin)){
62
+ if(!_slaveobj.Open(_no_giveup_rejoin)){
57
63
  // set error
58
- this->SetErrorMessage("Failed to open(join to) chmpx slave.");
64
+ SetError("Failed to open(join to) chmpx slave.");
59
65
  }
60
66
  }else{
61
67
  // set error
62
- this->SetErrorMessage("Failed to initialize k2hdkcslave object.");
68
+ SetError("Failed to initialize k2hdkcslave object.");
63
69
  }
64
70
  }
65
71
 
66
- void HandleOKCallback()
72
+ // handler for success
73
+ void OnOK() override
67
74
  {
68
- Nan::HandleScope scope;
69
- const int argc = 1;
70
- v8::Local<v8::Value> argv[argc] = { Nan::Null() };
75
+ Napi::Env env = Env();
76
+ Napi::HandleScope scope(env);
71
77
 
72
- if(callback){
73
- callback->Call(argc, argv);
78
+ if(!_callbackRef.IsEmpty()){
79
+ _callbackRef.Value().Call({ env.Null() });
74
80
  }else{
75
- Nan::ThrowSyntaxError("Internal error in async worker");
76
- return;
81
+ Napi::TypeError::New(env, "Internal error in async worker");
77
82
  }
78
83
  }
79
84
 
80
- void HandleErrorCallback()
81
- {
82
- Nan::HandleScope scope;
83
- const int argc = 1;
84
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
85
+ // handler for failure (by calling SetError)
86
+ void OnError(const Napi::Error& err) override
87
+ {
88
+ Napi::Env env = Env();
89
+ Napi::HandleScope scope(env);
85
90
 
86
- if(callback){
87
- callback->Call(argc, argv);
91
+ // The first argument is the error message.
92
+ if(!_callbackRef.IsEmpty()){
93
+ _callbackRef.Value().Call({ Napi::String::New(env, err.Value().ToString().Utf8Value()) });
88
94
  }else{
89
- Nan::ThrowSyntaxError("Internal error in async worker");
90
- return;
95
+ // Throw error
96
+ err.ThrowAsJavaScriptException();
91
97
  }
92
- }
98
+ }
93
99
 
94
100
  private:
95
- K2hdkcSlave* pslaveobj;
96
-
97
- bool is_set_conf;
98
- std::string conf;
99
- int16_t ctlport;
100
- std::string cuk;
101
- bool auto_rejoin;
102
- bool no_giveup_rejoin;
101
+ Napi::FunctionReference _callbackRef;
102
+ K2hdkcSlave& _slaveobj;
103
+ std::string _conf;
104
+ int16_t _ctlport;
105
+ std::string _cuk;
106
+ bool _auto_rejoin;
107
+ bool _no_giveup_rejoin;
103
108
  };
104
109
 
105
110
  //---------------------------------------------------------
106
111
  // GetValueWorker class
107
112
  //
108
- // Constructor: constructor(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pkey, const char* psubkey, bool is_check_attr, const char* ppass)
113
+ // Constructor: constructor(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& key, const std::string& subkey, bool is_check_attr, const std::string& pass)
109
114
  // Callback function: function(string error[, string value])
110
115
  //
111
116
  //---------------------------------------------------------
112
- class GetValueWorker : public Nan::AsyncWorker
117
+ class GetValueWorker : public Napi::AsyncWorker
113
118
  {
114
119
  public:
115
- GetValueWorker(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, const char* inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pkey, const char* psubkey, bool is_check_attr, const char* ppass) :
116
- Nan::AsyncWorker(callback), pslaveobj(pobj),
117
- is_set_conf(NULL != configuration), conf(configuration ? configuration : ""), ctlport(control_port), cuk(inputcuk ? inputcuk : ""), auto_rejoin(is_auto_rejoin), no_giveup_rejoin(is_nogiveup_rejoin),
118
- is_key_set(NULL != pkey), strkey(pkey ? pkey : ""), is_subkey_set(NULL != psubkey), strsubkey(psubkey ? psubkey : ""), attrchk(is_check_attr), is_pass_set(NULL != ppass), strpass(ppass ? ppass : ""), is_result_set(false), strresult("")
119
- {}
120
- ~GetValueWorker() {}
120
+ GetValueWorker(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& key, const std::string& subkey, bool is_check_attr, const std::string& pass) :
121
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)),
122
+ _slaveobj(slaveobj), _conf(configuration), _ctlport(control_port), _cuk(inputcuk), _auto_rejoin(is_auto_rejoin), _no_giveup_rejoin(is_nogiveup_rejoin), _strkey(key), _strsubkey(subkey), _attrchk(is_check_attr), _strpass(pass), _is_result_set(false), _strresult("")
123
+ {
124
+ _callbackRef.Ref();
125
+ }
126
+
127
+ ~GetValueWorker() override
128
+ {
129
+ if(_callbackRef){
130
+ _callbackRef.Unref();
131
+ _callbackRef.Reset();
132
+ }
133
+ }
121
134
 
122
- void Execute()
135
+ // Run on worker thread
136
+ void Execute() override
123
137
  {
124
- if(!pslaveobj && !is_set_conf){
138
+ if(!_slaveobj.GetChmCntrlObject() && _conf.empty()){
125
139
  // onetime connection mode needs configuration
126
- this->SetErrorMessage("No configuration is associated to async worker");
140
+ SetError("No configuration is associated to async worker");
127
141
  return;
128
142
  }
129
- if(!is_key_set){
130
- this->SetErrorMessage("Specified key is empty(null)");
143
+ if(_strkey.empty()){
144
+ SetError("Specified key is empty(null)");
131
145
  return;
132
146
  }
133
147
 
134
148
  // work
135
149
  dkcres_type_t rescode = DKC_NORESTYPE;
136
- if(is_subkey_set){
150
+ if(!_strsubkey.empty()){
137
151
  // subkey is specified, thus need to check the key has it.
138
152
  K2hdkcComGetSubkeys* pSubComObj;
139
- if(!pslaveobj){
140
- pSubComObj = GetOtSlaveK2hdkcComGetSubkeys(conf.c_str(), ctlport, (cuk.empty() ? NULL : cuk.c_str()), auto_rejoin, no_giveup_rejoin);
153
+ if(!_slaveobj.GetChmCntrlObject()){
154
+ pSubComObj = GetOtSlaveK2hdkcComGetSubkeys(_conf.c_str(), _ctlport, (_cuk.empty() ? NULL : _cuk.c_str()), _auto_rejoin, _no_giveup_rejoin);
141
155
  }else{
142
- pSubComObj = GetPmSlaveK2hdkcComGetSubkeys(pslaveobj);
156
+ pSubComObj = GetPmSlaveK2hdkcComGetSubkeys(&_slaveobj);
143
157
  }
144
158
  if(!pSubComObj){
145
- this->SetErrorMessage("Internal error: Could not create command object.");
159
+ SetError("Internal error: Could not create command object.");
146
160
  return;
147
161
  }
148
162
  // get subkey list in key
149
163
  K2HSubKeys* pSubKeys= NULL;
150
- if(!pSubComObj->CommandSend(reinterpret_cast<const unsigned char*>(strkey.c_str()), strkey.length() + 1, attrchk, &pSubKeys, &rescode) || !pSubKeys){
164
+ if(!pSubComObj->CommandSend(reinterpret_cast<const unsigned char*>(_strkey.c_str()), _strkey.length() + 1, _attrchk, &pSubKeys, &rescode) || !pSubKeys){
151
165
  // key does not have any subkey
152
166
  DKC_DELETE(pSubComObj);
153
- is_result_set = false;
154
167
  return;
155
168
  }
169
+ DKC_DELETE(pSubComObj);
156
170
 
157
171
  // convert subkey binary data to string array
158
172
  strarr_t strarr;
159
173
  pSubKeys->StringArray(strarr);
160
174
  DKC_DELETE(pSubKeys);
161
- DKC_DELETE(pSubComObj);
162
175
 
163
176
  // check subkey
164
177
  bool found = false;
165
178
  for(strarr_t::const_iterator iter = strarr.begin(); iter != strarr.end(); ++iter){
166
- if(0 == strcmp(iter->c_str(), strsubkey.c_str())){
179
+ if(0 == strcmp(iter->c_str(), _strsubkey.c_str())){
167
180
  found = true;
168
181
  break;
169
182
  }
170
183
  }
171
184
  if(!found){
172
185
  // not found subkey in key
173
- is_result_set = false;
174
186
  return;
175
187
  }
176
188
  // switch key to subkey
177
- strkey = strsubkey;
189
+ _strkey = _strsubkey;
178
190
  }
179
191
 
180
192
  // get value
181
193
  K2hdkcComGet* pComObj;
182
- if(!pslaveobj){
183
- pComObj = GetOtSlaveK2hdkcComGet(conf.c_str(), ctlport, (cuk.empty() ? NULL : cuk.c_str()), auto_rejoin, no_giveup_rejoin);
194
+ if(!_slaveobj.GetChmCntrlObject()){
195
+ pComObj = GetOtSlaveK2hdkcComGet(_conf.c_str(), _ctlport, (_cuk.empty() ? NULL : _cuk.c_str()), _auto_rejoin, _no_giveup_rejoin);
184
196
  }else{
185
- pComObj = GetPmSlaveK2hdkcComGet(pslaveobj);
197
+ pComObj = GetPmSlaveK2hdkcComGet(&_slaveobj);
186
198
  }
187
199
  if(!pComObj){
188
- this->SetErrorMessage("Internal error: Could not create command object.");
200
+ SetError("Internal error: Could not create command object.");
189
201
  return;
190
202
  }
203
+
191
204
  const unsigned char* pvaltmp = NULL;
192
205
  size_t valtmplen = 0L;
193
- bool result = pComObj->CommandSend(reinterpret_cast<const unsigned char*>(strkey.c_str()), strkey.length() + 1, attrchk, (is_pass_set ? strpass.c_str() : NULL), &pvaltmp, &valtmplen, &rescode);
206
+ bool result = pComObj->CommandSend(reinterpret_cast<const unsigned char*>(_strkey.c_str()), _strkey.length() + 1, _attrchk, (_strpass.empty() ? NULL : _strpass.c_str()), &pvaltmp, &valtmplen, &rescode);
194
207
  if(result && (pvaltmp && 0 < valtmplen)){
195
- strresult = std::string(reinterpret_cast<const char*>(pvaltmp), valtmplen);
196
- is_result_set = true;
197
- }else{
198
- is_result_set = false;
208
+ _strresult = std::string(reinterpret_cast<const char*>(pvaltmp), ('\0' == pvaltmp[valtmplen - 1] ? valtmplen - 1 : valtmplen));
209
+ _is_result_set = true;
199
210
  }
200
211
  DKC_DELETE(pComObj);
201
212
  }
202
213
 
203
- void HandleOKCallback()
214
+ // handler for success
215
+ void OnOK() override
204
216
  {
205
- Nan::HandleScope scope;
206
- const int argc = 2;
217
+ Napi::Env env = Env();
218
+ Napi::HandleScope scope(env);
207
219
 
208
- if(callback){
209
- if(is_result_set){
210
- v8::Local<v8::Value> argv[argc] = { Nan::Null(), Nan::New<v8::String>(strresult.c_str()).ToLocalChecked() };
211
- callback->Call(argc, argv);
220
+ if(!_callbackRef.IsEmpty()){
221
+ if(_is_result_set){
222
+ Napi::String valBuf = Napi::String::New(env, _strresult.c_str(), _strresult.length());
223
+ _callbackRef.Value().Call({ env.Null(), valBuf });
212
224
  }else{
213
- v8::Local<v8::Value> argv[argc] = { Nan::Null(), Nan::Null() };
214
- callback->Call(argc, argv);
225
+ _callbackRef.Value().Call({ env.Null(), env.Null() });
215
226
  }
216
227
  }else{
217
- Nan::ThrowSyntaxError("Internal error in async worker");
218
- return;
228
+ Napi::TypeError::New(env, "Internal error in async worker").ThrowAsJavaScriptException();
219
229
  }
220
230
  }
221
231
 
222
- void HandleErrorCallback()
223
- {
224
- Nan::HandleScope scope;
225
- const int argc = 1;
226
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
232
+ // handler for failure (by calling SetError)
233
+ void OnError(const Napi::Error& err) override
234
+ {
235
+ Napi::Env env = Env();
236
+ Napi::HandleScope scope(env);
227
237
 
228
- if(callback){
229
- callback->Call(argc, argv);
238
+ // The first argument is the error message.
239
+ if(!_callbackRef.IsEmpty()){
240
+ _callbackRef.Value().Call({ Napi::String::New(env, err.Value().ToString().Utf8Value()) });
230
241
  }else{
231
- Nan::ThrowSyntaxError("Internal error in async worker");
232
- return;
242
+ // Throw error
243
+ err.ThrowAsJavaScriptException();
233
244
  }
234
- }
245
+ }
235
246
 
236
247
  private:
237
- K2hdkcSlave* pslaveobj;
238
-
239
- bool is_set_conf;
240
- std::string conf;
241
- int16_t ctlport;
242
- std::string cuk;
243
- bool auto_rejoin;
244
- bool no_giveup_rejoin;
245
-
246
- bool is_key_set;
247
- std::string strkey;
248
- bool is_subkey_set;
249
- std::string strsubkey;
250
- bool attrchk;
251
- bool is_pass_set;
252
- std::string strpass;
253
-
254
- bool is_result_set;
255
- std::string strresult;
248
+ Napi::FunctionReference _callbackRef;
249
+ K2hdkcSlave& _slaveobj;
250
+ std::string _conf;
251
+ int16_t _ctlport;
252
+ std::string _cuk;
253
+ bool _auto_rejoin;
254
+ bool _no_giveup_rejoin;
255
+
256
+ std::string _strkey;
257
+ std::string _strsubkey;
258
+ bool _attrchk;
259
+ std::string _strpass;
260
+
261
+ bool _is_result_set;
262
+ std::string _strresult;
256
263
  };
257
264
 
258
265
  //---------------------------------------------------------
259
266
  // GetSubkeysWorker class
260
267
  //
261
- // Constructor: constructor(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pkey, bool is_check_attr)
268
+ // Constructor: constructor(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& key, bool is_check_attr)
262
269
  // Callback function: function(string error, array subkeys)
263
270
  //
264
271
  //---------------------------------------------------------
265
- class GetSubkeysWorker : public Nan::AsyncWorker
272
+ class GetSubkeysWorker : public Napi::AsyncWorker
266
273
  {
267
274
  public:
268
- GetSubkeysWorker(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, const char* inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pkey, bool is_check_attr) :
269
- Nan::AsyncWorker(callback), pslaveobj(pobj),
270
- is_set_conf(NULL != configuration), conf(configuration ? configuration : ""), ctlport(control_port), cuk(inputcuk ? inputcuk : ""), auto_rejoin(is_auto_rejoin), no_giveup_rejoin(is_nogiveup_rejoin), is_key_set(NULL != pkey), strkey(pkey ? pkey : ""), attrchk(is_check_attr)
271
- {}
272
- ~GetSubkeysWorker() {}
275
+ GetSubkeysWorker(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& key, bool is_check_attr) :
276
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)),
277
+ _slaveobj(slaveobj), _conf(configuration), _ctlport(control_port), _cuk(inputcuk), _auto_rejoin(is_auto_rejoin), _no_giveup_rejoin(is_nogiveup_rejoin), _strkey(key), _attrchk(is_check_attr)
278
+ {
279
+ _callbackRef.Ref();
280
+ }
273
281
 
274
- void Execute()
282
+ ~GetSubkeysWorker() override
275
283
  {
276
- if(!pslaveobj && !is_set_conf){
284
+ if(_callbackRef){
285
+ _callbackRef.Unref();
286
+ _callbackRef.Reset();
287
+ }
288
+ }
289
+
290
+ // Run on worker thread
291
+ void Execute() override
292
+ {
293
+ if(!_slaveobj.GetChmCntrlObject() && _conf.empty()){
277
294
  // onetime connection mode needs configuration
278
- this->SetErrorMessage("No configuration is associated to async worker");
295
+ SetError("No configuration is associated to async worker");
279
296
  return;
280
297
  }
281
- if(!is_key_set){
282
- this->SetErrorMessage("Specified key is empty(null)");
298
+ if(_strkey.empty()){
299
+ SetError("Specified key is empty(null)");
283
300
  return;
284
301
  }
285
302
 
286
303
  // get command object
287
304
  K2hdkcComGetSubkeys* pComObj;
288
- if(!pslaveobj){
289
- pComObj = GetOtSlaveK2hdkcComGetSubkeys(conf.c_str(), ctlport, (cuk.empty() ? NULL : cuk.c_str()), auto_rejoin, no_giveup_rejoin);
305
+ if(!_slaveobj.GetChmCntrlObject()){
306
+ pComObj = GetOtSlaveK2hdkcComGetSubkeys(_conf.c_str(), _ctlport, (_cuk.empty() ? NULL : _cuk.c_str()), _auto_rejoin, _no_giveup_rejoin);
290
307
  }else{
291
- pComObj = GetPmSlaveK2hdkcComGetSubkeys(pslaveobj);
308
+ pComObj = GetPmSlaveK2hdkcComGetSubkeys(&_slaveobj);
292
309
  }
293
310
  if(!pComObj){
294
- this->SetErrorMessage("Internal error: Could not create command object.");
311
+ SetError("Internal error: Could not create command object.");
295
312
  return;
296
313
  }
297
314
 
298
315
  // get subkey list in key
299
316
  dkcres_type_t rescode = DKC_NORESTYPE;
300
317
  K2HSubKeys* pSubKeys= NULL;
301
- if(!pComObj->CommandSend(reinterpret_cast<const unsigned char*>(strkey.c_str()), strkey.length() + 1, attrchk, &pSubKeys, &rescode) || !pSubKeys){
318
+ if(!pComObj->CommandSend(reinterpret_cast<const unsigned char*>(_strkey.c_str()), _strkey.length() + 1, _attrchk, &pSubKeys, &rescode) || !pSubKeys){
302
319
  // key does not have any subkey
303
- this->SetErrorMessage("Failed to get subkey because the key does not have any subkey.");
320
+ SetError("Failed to get subkey because the key does not have any subkey.");
304
321
  }else{
305
322
  // convert subkey binary data to string array
306
323
  subkey_array.clear();
@@ -308,108 +325,125 @@ class GetSubkeysWorker : public Nan::AsyncWorker
308
325
  DKC_DELETE(pSubKeys);
309
326
 
310
327
  if(0 == subkey_array.size()){
311
- this->SetErrorMessage("Failed to get subkey because the key does not have any subkey.");
328
+ SetError("Failed to get subkey because the key does not have any subkey.");
312
329
  }
313
330
  }
314
331
  DKC_DELETE(pComObj);
315
332
  }
316
333
 
317
- void HandleOKCallback()
334
+ // handler for success
335
+ void OnOK() override
318
336
  {
319
- Nan::HandleScope scope;
320
- v8::Local<v8::Array> retarr = Nan::New<v8::Array>();
321
- int pos = 0 ;
322
- for(strarr_t::const_iterator iter = subkey_array.begin(); iter != subkey_array.end(); ++iter, ++pos){
323
- Nan::Set(retarr, pos, Nan::New<v8::String>(iter->c_str()).ToLocalChecked());
337
+ Napi::Env env = Env();
338
+ Napi::HandleScope scope(env);
339
+
340
+ Napi::Array retarr = Napi::Array::New(env, subkey_array.size());
341
+ uint32_t pos = 0;
342
+ for(const auto &str: subkey_array){
343
+ std::string strtmp(str);
344
+ while(!strtmp.empty()){
345
+ unsigned char tmpch = static_cast<unsigned char>(strtmp.back());
346
+ if('\0' != tmpch && !std::isspace(tmpch)){
347
+ break;
348
+ }
349
+ strtmp.pop_back();
350
+ }
351
+ retarr.Set(pos++, Napi::String::New(env, strtmp));
324
352
  }
325
- const int argc = 2;
326
- v8::Local<v8::Value> argv[argc] = { Nan::Null(), retarr };
327
353
 
328
- if(callback){
329
- callback->Call(argc, argv);
354
+ if(!_callbackRef.IsEmpty()){
355
+ _callbackRef.Value().Call({ env.Null(), retarr });
330
356
  }else{
331
- Nan::ThrowSyntaxError("Internal error in async worker");
332
- return;
357
+ Napi::TypeError::New(env, "Internal error in async worker").ThrowAsJavaScriptException();
333
358
  }
334
359
  }
335
360
 
336
- void HandleErrorCallback()
337
- {
338
- Nan::HandleScope scope;
339
- const int argc = 2;
340
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked(), Nan::Null() };
361
+ // handler for failure (by calling SetError)
362
+ void OnError(const Napi::Error& err) override
363
+ {
364
+ Napi::Env env = Env();
365
+ Napi::HandleScope scope(env);
341
366
 
342
- if(callback){
343
- callback->Call(argc, argv);
367
+ // The first argument is the error message.
368
+ if(!_callbackRef.IsEmpty()){
369
+ _callbackRef.Value().Call({ Napi::String::New(env, err.Value().ToString().Utf8Value()) });
344
370
  }else{
345
- Nan::ThrowSyntaxError("Internal error in async worker");
346
- return;
371
+ // Throw error
372
+ err.ThrowAsJavaScriptException();
347
373
  }
348
- }
374
+ }
349
375
 
350
376
  private:
351
- K2hdkcSlave* pslaveobj;
352
-
353
- bool is_set_conf;
354
- std::string conf;
355
- int16_t ctlport;
356
- std::string cuk;
357
- bool auto_rejoin;
358
- bool no_giveup_rejoin;
359
- bool is_key_set;
360
-
361
- std::string strkey;
362
- bool attrchk;
363
-
364
- strarr_t subkey_array;
377
+ Napi::FunctionReference _callbackRef;
378
+ K2hdkcSlave& _slaveobj;
379
+ std::string _conf;
380
+ int16_t _ctlport;
381
+ std::string _cuk;
382
+ bool _auto_rejoin;
383
+ bool _no_giveup_rejoin;
384
+
385
+ std::string _strkey;
386
+ bool _attrchk;
387
+
388
+ strarr_t subkey_array;
365
389
  };
366
390
 
367
391
  //---------------------------------------------------------
368
392
  // GetAttrsWorker class
369
393
  //
370
- // Constructor: constructor(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pkey)
394
+ // Constructor: constructor(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& key)
371
395
  // Callback function: function(string error, array attribute_keys)
372
396
  //
373
397
  //---------------------------------------------------------
374
- class GetAttrsWorker : public Nan::AsyncWorker
398
+ class GetAttrsWorker : public Napi::AsyncWorker
375
399
  {
376
400
  public:
377
- GetAttrsWorker(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, const char* inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pkey) :
378
- Nan::AsyncWorker(callback), pslaveobj(pobj),
379
- is_set_conf(NULL != configuration), conf(configuration ? configuration : ""), ctlport(control_port), cuk(inputcuk ? inputcuk : ""), auto_rejoin(is_auto_rejoin), no_giveup_rejoin(is_nogiveup_rejoin), is_key_set(NULL != pkey), strkey(pkey ? pkey : "")
380
- {}
381
- ~GetAttrsWorker() {}
401
+ GetAttrsWorker(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& key) :
402
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)),
403
+ _slaveobj(slaveobj), _conf(configuration), _ctlport(control_port), _cuk(inputcuk), _auto_rejoin(is_auto_rejoin), _no_giveup_rejoin(is_nogiveup_rejoin), _strkey(key)
404
+ {
405
+ _callbackRef.Ref();
406
+ }
407
+
408
+ ~GetAttrsWorker() override
409
+ {
410
+ if(_callbackRef){
411
+ _callbackRef.Unref();
412
+ _callbackRef.Reset();
413
+ }
414
+ }
382
415
 
383
- void Execute()
416
+ // Run on worker thread
417
+ void Execute() override
384
418
  {
385
- if(!pslaveobj && !is_set_conf){
419
+ if(!_slaveobj.GetChmCntrlObject() && _conf.empty()){
386
420
  // onetime connection mode needs configuration
387
- this->SetErrorMessage("No configuration is associated to async worker");
421
+ SetError("No configuration is associated to async worker");
388
422
  return;
389
423
  }
390
- if(!is_key_set){
391
- this->SetErrorMessage("Specified key is empty(null)");
424
+ if(_strkey.empty()){
425
+ SetError("Specified key is empty(null)");
392
426
  return;
393
427
  }
394
428
 
395
429
  // get command object
396
430
  K2hdkcComGetAttrs* pComObj;
397
- if(!pslaveobj){
398
- pComObj = GetOtSlaveK2hdkcComGetAttrs(conf.c_str(), ctlport, (cuk.empty() ? NULL : cuk.c_str()), auto_rejoin, no_giveup_rejoin);
431
+ if(!_slaveobj.GetChmCntrlObject()){
432
+ pComObj = GetOtSlaveK2hdkcComGetAttrs(_conf.c_str(), _ctlport, (_cuk.empty() ? NULL : _cuk.c_str()), _auto_rejoin, _no_giveup_rejoin);
399
433
  }else{
400
- pComObj = GetPmSlaveK2hdkcComGetAttrs(pslaveobj);
434
+ pComObj = GetPmSlaveK2hdkcComGetAttrs(&_slaveobj);
401
435
  }
402
436
  if(!pComObj){
403
- this->SetErrorMessage("Internal error: Could not create command object.");
437
+ SetError("Internal error: Could not create command object.");
404
438
  return;
405
439
  }
406
440
 
407
441
  // get attribute list in key
408
442
  dkcres_type_t rescode = DKC_NORESTYPE;
409
443
  K2HAttrs* pAttrs = NULL;
410
- if(!pComObj->CommandSend(reinterpret_cast<const unsigned char*>(strkey.c_str()), strkey.length() + 1, &pAttrs, &rescode) || !pAttrs){
444
+ if(!pComObj->CommandSend(reinterpret_cast<const unsigned char*>(_strkey.c_str()), _strkey.length() + 1, &pAttrs, &rescode) || !pAttrs){
411
445
  // key does not have any attribute key
412
- this->SetErrorMessage("Failed to get attribute keys because the key does not have any attribute.");
446
+ SetError("Failed to get attribute keys because the key does not have any attribute.");
413
447
  }else{
414
448
  // convert attribute key binary data to string array
415
449
  attrs_array.clear();
@@ -417,1377 +451,1431 @@ class GetAttrsWorker : public Nan::AsyncWorker
417
451
  DKC_DELETE(pAttrs);
418
452
 
419
453
  if(0 == attrs_array.size()){
420
- this->SetErrorMessage("Failed to get attribute keys because the key does not have any attribute.");
454
+ SetError("Failed to get attribute keys because the key does not have any attribute.");
421
455
  }
422
456
  }
423
457
  DKC_DELETE(pComObj);
424
458
  }
425
459
 
426
- void HandleOKCallback()
460
+ // handler for success
461
+ void OnOK() override
427
462
  {
428
- Nan::HandleScope scope;
429
- v8::Local<v8::Array> retarr = Nan::New<v8::Array>();
430
- int pos = 0 ;
431
- for(strarr_t::const_iterator iter = attrs_array.begin(); iter != attrs_array.end(); ++iter, ++pos){
432
- Nan::Set(retarr, pos, Nan::New<v8::String>(iter->c_str()).ToLocalChecked());
463
+ Napi::Env env = Env();
464
+ Napi::HandleScope scope(env);
465
+
466
+ Napi::Array retarr = Napi::Array::New(env, attrs_array.size());
467
+ uint32_t pos = 0;
468
+ for(const auto &str: attrs_array){
469
+ std::string strtmp(str);
470
+ while(!strtmp.empty()){
471
+ unsigned char tmpch = static_cast<unsigned char>(strtmp.back());
472
+ if('\0' != tmpch && !std::isspace(tmpch)){
473
+ break;
474
+ }
475
+ strtmp.pop_back();
476
+ }
477
+ retarr.Set(pos++, Napi::String::New(env, strtmp));
433
478
  }
434
- const int argc = 2;
435
- v8::Local<v8::Value> argv[argc] = { Nan::Null(), retarr };
436
479
 
437
- if(callback){
438
- callback->Call(argc, argv);
480
+ if(!_callbackRef.IsEmpty()){
481
+ _callbackRef.Value().Call({ env.Null(), retarr });
439
482
  }else{
440
- Nan::ThrowSyntaxError("Internal error in async worker");
441
- return;
483
+ Napi::TypeError::New(env, "Internal error in async worker").ThrowAsJavaScriptException();
442
484
  }
443
485
  }
444
486
 
445
- void HandleErrorCallback()
446
- {
447
- Nan::HandleScope scope;
448
- const int argc = 2;
449
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked(), Nan::Null() };
487
+ // handler for failure (by calling SetError)
488
+ void OnError(const Napi::Error& err) override
489
+ {
490
+ Napi::Env env = Env();
491
+ Napi::HandleScope scope(env);
450
492
 
451
- if(callback){
452
- callback->Call(argc, argv);
493
+ // The first argument is the error message.
494
+ if(!_callbackRef.IsEmpty()){
495
+ _callbackRef.Value().Call({ Napi::String::New(env, err.Value().ToString().Utf8Value()) });
453
496
  }else{
454
- Nan::ThrowSyntaxError("Internal error in async worker");
455
- return;
497
+ // Throw error
498
+ err.ThrowAsJavaScriptException();
456
499
  }
457
- }
500
+ }
458
501
 
459
502
  private:
460
- K2hdkcSlave* pslaveobj;
461
-
462
- bool is_set_conf;
463
- std::string conf;
464
- int16_t ctlport;
465
- std::string cuk;
466
- bool auto_rejoin;
467
- bool no_giveup_rejoin;
468
- bool is_key_set;
469
-
470
- std::string strkey;
471
-
472
- strarr_t attrs_array;
503
+ Napi::FunctionReference _callbackRef;
504
+ K2hdkcSlave& _slaveobj;
505
+ std::string _conf;
506
+ int16_t _ctlport;
507
+ std::string _cuk;
508
+ bool _auto_rejoin;
509
+ bool _no_giveup_rejoin;
510
+ std::string _strkey;
511
+
512
+ strarr_t attrs_array;
473
513
  };
474
514
 
475
515
  //---------------------------------------------------------
476
516
  // SetValueWorker class
477
517
  //
478
- // Constructor: constructor(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pkey, const char* pval, const char* psubkey, const char* ppass, const time_t* pexpire)
518
+ // Constructor: constructor(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& key, const std::string& val, const std::string& subkey, const std::string& pass, const time_t input_expire)
479
519
  // Callback function: function(string error)
480
520
  //
481
521
  //---------------------------------------------------------
482
- class SetValueWorker : public Nan::AsyncWorker
522
+ class SetValueWorker : public Napi::AsyncWorker
483
523
  {
484
524
  public:
485
- SetValueWorker(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, const char* inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pkey, const char* pval, const char* psubkey, const char* ppass, const time_t* pexpire) :
486
- Nan::AsyncWorker(callback), pslaveobj(pobj),
487
- is_set_conf(NULL != configuration), conf(configuration ? configuration : ""), ctlport(control_port), cuk(inputcuk ? inputcuk : ""), auto_rejoin(is_auto_rejoin), no_giveup_rejoin(is_nogiveup_rejoin),
488
- is_key_set(NULL != pkey), strkey(pkey ? pkey : ""), is_val_set(NULL != pval), strval(pval ? pval : ""), is_subkey_set(NULL != psubkey), strsubkey(psubkey ? psubkey : ""), is_pass_set(NULL != ppass), strpass(ppass ? ppass : ""), expire(pexpire ? *pexpire : 0)
489
- {}
490
- ~SetValueWorker() {}
525
+ SetValueWorker(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& key, const std::string& val, const std::string& subkey, const std::string& pass, const time_t input_expire) :
526
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)),
527
+ _slaveobj(slaveobj), _conf(configuration), _ctlport(control_port), _cuk(inputcuk), _auto_rejoin(is_auto_rejoin), _no_giveup_rejoin(is_nogiveup_rejoin), _strkey(key), _strval(val), _strsubkey(subkey), _strpass(pass), _expire(input_expire)
528
+ {
529
+ _callbackRef.Ref();
530
+ }
491
531
 
492
- void Execute()
532
+ ~SetValueWorker() override
493
533
  {
494
- if(!pslaveobj && !is_set_conf){
534
+ if(_callbackRef){
535
+ _callbackRef.Unref();
536
+ _callbackRef.Reset();
537
+ }
538
+ }
539
+
540
+ // Run on worker thread
541
+ void Execute() override
542
+ {
543
+ if(!_slaveobj.GetChmCntrlObject() && _conf.empty()){
495
544
  // onetime connection mode needs configuration
496
- this->SetErrorMessage("No configuration is associated to async worker");
545
+ SetError("No configuration is associated to async worker");
497
546
  return;
498
547
  }
499
- if(!is_key_set){
500
- this->SetErrorMessage("Specified key is empty(null)");
548
+ if(_strkey.empty()){
549
+ SetError("Specified key is empty(null)");
501
550
  return;
502
551
  }
503
552
 
504
553
  // work
505
554
  dkcres_type_t rescode = DKC_NORESTYPE;
506
- if(is_subkey_set){
555
+ if(!_strsubkey.empty()){
507
556
  // subkey is specified, set value into subkey
508
557
  K2hdkcComAddSubkey* pComObj;
509
- if(!pslaveobj){
510
- pComObj = GetOtSlaveK2hdkcComAddSubkey(conf.c_str(), ctlport, (cuk.empty() ? NULL : cuk.c_str()), auto_rejoin, no_giveup_rejoin);
558
+ if(!_slaveobj.GetChmCntrlObject()){
559
+ pComObj = GetOtSlaveK2hdkcComAddSubkey(_conf.c_str(), _ctlport, (_cuk.empty() ? NULL : _cuk.c_str()), _auto_rejoin, _no_giveup_rejoin);
511
560
  }else{
512
- pComObj = GetPmSlaveK2hdkcComAddSubkey(pslaveobj);
561
+ pComObj = GetPmSlaveK2hdkcComAddSubkey(&_slaveobj);
513
562
  }
514
563
  if(!pComObj){
515
- this->SetErrorMessage("Internal error: Could not create command object.");
564
+ SetError("Internal error: Could not create command object.");
516
565
  return;
517
566
  }
518
- if(!pComObj->CommandSend(reinterpret_cast<const unsigned char*>(strkey.c_str()), strkey.length() + 1, reinterpret_cast<const unsigned char*>(strsubkey.c_str()), strsubkey.length() + 1, (is_val_set ? reinterpret_cast<const unsigned char*>(strval.c_str()) : NULL), (is_val_set ? strval.length() + 1 : 0), true, (is_pass_set ? strpass.c_str() : NULL), (expire > 0 ? &expire : NULL), &rescode)){
519
- this->SetErrorMessage("Failed to set value into subkey/key.");
567
+ if(!pComObj->CommandSend(reinterpret_cast<const unsigned char*>(_strkey.c_str()), _strkey.length() + 1, reinterpret_cast<const unsigned char*>(_strsubkey.c_str()), _strsubkey.length() + 1, (_strval.empty() ? NULL : reinterpret_cast<const unsigned char*>(_strval.c_str())), (_strval.empty() ? 0 : _strval.length() + 1), true, (_strpass.empty() ? NULL : _strpass.c_str()), (_expire > 0 ? &_expire : NULL), &rescode)){
568
+ SetError("Failed to set value into subkey/key.");
520
569
  }
521
570
  DKC_DELETE(pComObj);
522
571
  }else{
523
572
  // set value to key
524
573
  K2hdkcComSet* pComObj;
525
- if(!pslaveobj){
526
- pComObj = GetOtSlaveK2hdkcComSet(conf.c_str(), ctlport, (cuk.empty() ? NULL : cuk.c_str()), auto_rejoin, no_giveup_rejoin);
574
+ if(!_slaveobj.GetChmCntrlObject()){
575
+ pComObj = GetOtSlaveK2hdkcComSet(_conf.c_str(), _ctlport, (_cuk.empty() ? NULL : _cuk.c_str()), _auto_rejoin, _no_giveup_rejoin);
527
576
  }else{
528
- pComObj = GetPmSlaveK2hdkcComSet(pslaveobj);
577
+ pComObj = GetPmSlaveK2hdkcComSet(&_slaveobj);
529
578
  }
530
579
  if(!pComObj){
531
- this->SetErrorMessage("Internal error: Could not create command object.");
580
+ SetError("Internal error: Could not create command object.");
532
581
  return;
533
582
  }
534
- if(!pComObj->CommandSend(reinterpret_cast<const unsigned char*>(strkey.c_str()), strkey.length() + 1, (is_val_set ? reinterpret_cast<const unsigned char*>(strval.c_str()) : NULL), (is_val_set ? strval.length() + 1 : 0), false, (is_pass_set ? strpass.c_str() : NULL), (expire > 0 ? &expire : NULL), &rescode)){
535
- this->SetErrorMessage("Failed to set value into key.");
583
+ if(!pComObj->CommandSend(reinterpret_cast<const unsigned char*>(_strkey.c_str()), _strkey.length() + 1, (_strval.empty() ? NULL : reinterpret_cast<const unsigned char*>(_strval.c_str())), (_strval.empty() ? 0 : _strval.length() + 1), false, (_strpass.empty() ? NULL : _strpass.c_str()), (_expire > 0 ? &_expire : NULL), &rescode)){
584
+ SetError("Failed to set value into key.");
536
585
  }
537
586
  DKC_DELETE(pComObj);
538
587
  }
539
588
  }
540
589
 
541
- void HandleOKCallback()
590
+ // handler for success
591
+ void OnOK() override
542
592
  {
543
- Nan::HandleScope scope;
544
- const int argc = 1;
545
- v8::Local<v8::Value> argv[argc] = { Nan::Null() };
593
+ Napi::Env env = Env();
594
+ Napi::HandleScope scope(env);
546
595
 
547
- if(callback){
548
- callback->Call(argc, argv);
596
+ if(!_callbackRef.IsEmpty()){
597
+ _callbackRef.Value().Call({ env.Null() });
549
598
  }else{
550
- Nan::ThrowSyntaxError("Internal error in async worker");
551
- return;
599
+ Napi::TypeError::New(env, "Internal error in async worker");
552
600
  }
553
601
  }
554
602
 
555
- void HandleErrorCallback()
556
- {
557
- Nan::HandleScope scope;
558
- const int argc = 1;
559
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
603
+ // handler for failure (by calling SetError)
604
+ void OnError(const Napi::Error& err) override
605
+ {
606
+ Napi::Env env = Env();
607
+ Napi::HandleScope scope(env);
560
608
 
561
- if(callback){
562
- callback->Call(argc, argv);
609
+ // The first argument is the error message.
610
+ if(!_callbackRef.IsEmpty()){
611
+ _callbackRef.Value().Call({ Napi::String::New(env, err.Value().ToString().Utf8Value()) });
563
612
  }else{
564
- Nan::ThrowSyntaxError("Internal error in async worker");
565
- return;
613
+ // Throw error
614
+ err.ThrowAsJavaScriptException();
566
615
  }
567
- }
616
+ }
568
617
 
569
618
  private:
570
- K2hdkcSlave* pslaveobj;
571
-
572
- bool is_set_conf;
573
- std::string conf;
574
- int16_t ctlport;
575
- std::string cuk;
576
- bool auto_rejoin;
577
- bool no_giveup_rejoin;
578
-
579
- bool is_key_set;
580
- std::string strkey;
581
- bool is_val_set;
582
- std::string strval;
583
- bool is_subkey_set;
584
- std::string strsubkey;
585
- bool is_pass_set;
586
- std::string strpass;
587
- time_t expire;
619
+ Napi::FunctionReference _callbackRef;
620
+ K2hdkcSlave& _slaveobj;
621
+ std::string _conf;
622
+ int16_t _ctlport;
623
+ std::string _cuk;
624
+ bool _auto_rejoin;
625
+ bool _no_giveup_rejoin;
626
+
627
+ std::string _strkey;
628
+ std::string _strval;
629
+ std::string _strsubkey;
630
+ std::string _strpass;
631
+ time_t _expire;
588
632
  };
589
633
 
590
634
  //---------------------------------------------------------
591
635
  // SetSubkeysWorker class
592
636
  //
593
- // Constructor: constructor(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pkey, unsigned char* psubkeys, size_t subkeylength)
637
+ // Constructor: constructor(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& key, unsigned char* psubkeys, size_t subkeylength)
594
638
  // Callback function: function(string error)
595
639
  //
596
640
  //---------------------------------------------------------
597
- class SetSubkeysWorker : public Nan::AsyncWorker
641
+ class SetSubkeysWorker : public Napi::AsyncWorker
598
642
  {
599
643
  public:
600
- SetSubkeysWorker(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, const char* inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pkey, unsigned char* psubkeys, size_t subkeylength) :
601
- Nan::AsyncWorker(callback), pslaveobj(pobj),
602
- is_set_conf(NULL != configuration), conf(configuration ? configuration : ""), ctlport(control_port), cuk(inputcuk ? inputcuk : ""), auto_rejoin(is_auto_rejoin), no_giveup_rejoin(is_nogiveup_rejoin),
603
- is_key_set(NULL != pkey), strkey(pkey ? pkey : ""), bysubkeys(NULL), skeylen(0)
644
+ SetSubkeysWorker(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& key, unsigned char* psubkeys, size_t subkeylength) :
645
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)),
646
+ _slaveobj(slaveobj), _conf(configuration), _ctlport(control_port), _cuk(inputcuk), _auto_rejoin(is_auto_rejoin), _no_giveup_rejoin(is_nogiveup_rejoin), _strkey(key), _bysubkeys(NULL), _skeylen(0)
604
647
  {
648
+ _callbackRef.Ref();
649
+
605
650
  if(psubkeys && 0UL < subkeylength){
606
- bysubkeys = k2hbindup(psubkeys, subkeylength);
607
- skeylen = subkeylength;
651
+ _bysubkeys = k2hbindup(psubkeys, subkeylength);
652
+ _skeylen = subkeylength;
608
653
  }
609
654
  }
610
655
 
611
656
  ~SetSubkeysWorker()
612
657
  {
613
- K2H_Free(bysubkeys);
658
+ if(_callbackRef){
659
+ _callbackRef.Unref();
660
+ _callbackRef.Reset();
661
+ }
662
+ K2H_Free(_bysubkeys);
614
663
  }
615
664
 
616
- void Execute()
665
+ // Run on worker thread
666
+ void Execute() override
617
667
  {
618
- if(!pslaveobj && !is_set_conf){
668
+ if(!_slaveobj.GetChmCntrlObject() && _conf.empty()){
619
669
  // onetime connection mode needs configuration
620
- this->SetErrorMessage("No configuration is associated to async worker");
670
+ SetError("No configuration is associated to async worker");
621
671
  return;
622
672
  }
623
- if(!is_key_set){
624
- this->SetErrorMessage("Specified key is empty(null)");
673
+ if(_strkey.empty()){
674
+ SetError("Specified key is empty(null)");
625
675
  return;
626
676
  }
627
677
 
628
678
  // work
629
679
  K2hdkcComSetSubkeys* pComObj;
630
- if(!pslaveobj){
631
- pComObj = GetOtSlaveK2hdkcComSetSubkeys(conf.c_str(), ctlport, (cuk.empty() ? NULL : cuk.c_str()), auto_rejoin, no_giveup_rejoin);
680
+ if(!_slaveobj.GetChmCntrlObject()){
681
+ pComObj = GetOtSlaveK2hdkcComSetSubkeys(_conf.c_str(), _ctlport, (_cuk.empty() ? NULL : _cuk.c_str()), _auto_rejoin, _no_giveup_rejoin);
632
682
  }else{
633
- pComObj = GetPmSlaveK2hdkcComSetSubkeys(pslaveobj);
683
+ pComObj = GetPmSlaveK2hdkcComSetSubkeys(&_slaveobj);
634
684
  }
635
685
  if(!pComObj){
636
- this->SetErrorMessage("Internal error: Could not create command object.");
686
+ SetError("Internal error: Could not create command object.");
637
687
  return;
638
688
  }
639
689
 
640
690
  bool result = false;
641
691
  dkcres_type_t rescode = DKC_NORESTYPE;
642
- if(bysubkeys && 0UL < skeylen){
692
+ if(_bysubkeys && 0UL < _skeylen){
643
693
  // set subkeys to key
644
- result = pComObj->CommandSend(reinterpret_cast<const unsigned char*>(strkey.c_str()), strkey.length() + 1, bysubkeys, skeylen, &rescode);
694
+ result = pComObj->CommandSend(reinterpret_cast<const unsigned char*>(_strkey.c_str()), _strkey.length() + 1, _bysubkeys, _skeylen, &rescode);
645
695
  }else{
646
696
  // clear subkeys
647
- result = pComObj->ClearSubkeysCommandSend(reinterpret_cast<const unsigned char*>(strkey.c_str()), strkey.length() + 1, &rescode);
697
+ result = pComObj->ClearSubkeysCommandSend(reinterpret_cast<const unsigned char*>(_strkey.c_str()), _strkey.length() + 1, &rescode);
648
698
  }
649
699
  DKC_DELETE(pComObj);
650
700
 
651
701
  if(!result){
652
- if(bysubkeys && 0UL < skeylen){
653
- this->SetErrorMessage("Failed to set subkeys into key.");
702
+ if(_bysubkeys && 0UL < _skeylen){
703
+ SetError("Failed to set subkeys into key.");
654
704
  }else{
655
- this->SetErrorMessage("Failed to clear subkeys in key.");
705
+ SetError("Failed to clear subkeys in key.");
656
706
  }
657
707
  }
658
708
  }
659
709
 
660
- void HandleOKCallback()
710
+ // handler for success
711
+ void OnOK() override
661
712
  {
662
- Nan::HandleScope scope;
663
- const int argc = 1;
664
- v8::Local<v8::Value> argv[argc] = { Nan::Null() };
713
+ Napi::Env env = Env();
714
+ Napi::HandleScope scope(env);
665
715
 
666
- if(callback){
667
- callback->Call(argc, argv);
716
+ if(!_callbackRef.IsEmpty()){
717
+ _callbackRef.Value().Call({ env.Null() });
668
718
  }else{
669
- Nan::ThrowSyntaxError("Internal error in async worker");
670
- return;
719
+ Napi::TypeError::New(env, "Internal error in async worker");
671
720
  }
672
721
  }
673
722
 
674
- void HandleErrorCallback()
675
- {
676
- Nan::HandleScope scope;
677
- const int argc = 1;
678
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
723
+ // handler for failure (by calling SetError)
724
+ void OnError(const Napi::Error& err) override
725
+ {
726
+ Napi::Env env = Env();
727
+ Napi::HandleScope scope(env);
679
728
 
680
- if(callback){
681
- callback->Call(argc, argv);
729
+ // The first argument is the error message.
730
+ if(!_callbackRef.IsEmpty()){
731
+ _callbackRef.Value().Call({ Napi::String::New(env, err.Value().ToString().Utf8Value()) });
682
732
  }else{
683
- Nan::ThrowSyntaxError("Internal error in async worker");
684
- return;
733
+ // Throw error
734
+ err.ThrowAsJavaScriptException();
685
735
  }
686
- }
736
+ }
687
737
 
688
738
  private:
689
- K2hdkcSlave* pslaveobj;
690
-
691
- bool is_set_conf;
692
- std::string conf;
693
- int16_t ctlport;
694
- std::string cuk;
695
- bool auto_rejoin;
696
- bool no_giveup_rejoin;
697
-
698
- bool is_key_set;
699
- std::string strkey;
700
- unsigned char* bysubkeys;
701
- size_t skeylen;
739
+ Napi::FunctionReference _callbackRef;
740
+ K2hdkcSlave& _slaveobj;
741
+ std::string _conf;
742
+ int16_t _ctlport;
743
+ std::string _cuk;
744
+ bool _auto_rejoin;
745
+ bool _no_giveup_rejoin;
746
+
747
+ std::string _strkey;
748
+ unsigned char* _bysubkeys;
749
+ size_t _skeylen;
702
750
  };
703
751
 
704
752
  //---------------------------------------------------------
705
753
  // SetAllWorker class
706
754
  //
707
- // Constructor: constructor(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pkey, const char* pval, unsigned char* psubkeys, size_t subkeylength, const char* ppass, const time_t* pexpire)
755
+ // Constructor: constructor(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& key, const std::string& val, unsigned char* psubkeys, size_t subkeylength, const std::string& pass, const time_t input_expire)
708
756
  // Callback function: function(string error)
709
757
  //
710
758
  //---------------------------------------------------------
711
- class SetAllWorker : public Nan::AsyncWorker
759
+ class SetAllWorker : public Napi::AsyncWorker
712
760
  {
713
761
  public:
714
- SetAllWorker(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, const char* inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pkey, const char* pval, unsigned char* psubkeys, size_t subkeylength, const char* ppass, const time_t* pexpire) :
715
- Nan::AsyncWorker(callback), pslaveobj(pobj),
716
- is_set_conf(NULL != configuration), conf(configuration ? configuration : ""), ctlport(control_port), cuk(inputcuk ? inputcuk : ""), auto_rejoin(is_auto_rejoin), no_giveup_rejoin(is_nogiveup_rejoin),
717
- is_key_set(NULL != pkey), strkey(pkey ? pkey : ""), is_val_set(NULL != pval), strval(pval ? pval : ""), bysubkeys(NULL), skeylen(0), is_pass_set(NULL != ppass), strpass(ppass ? ppass : ""), expire(pexpire ? *pexpire : 0)
762
+ SetAllWorker(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& key, const std::string& val, unsigned char* psubkeys, size_t subkeylength, const std::string& pass, const time_t input_expire) :
763
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)),
764
+ _slaveobj(slaveobj), _conf(configuration), _ctlport(control_port), _cuk(inputcuk), _auto_rejoin(is_auto_rejoin), _no_giveup_rejoin(is_nogiveup_rejoin), _strkey(key), _strval(val), _bysubkeys(NULL), _skeylen(0), _strpass(pass), _expire(input_expire)
718
765
  {
766
+ _callbackRef.Ref();
767
+
719
768
  if(psubkeys && 0UL < subkeylength){
720
- bysubkeys = k2hbindup(psubkeys, subkeylength);
721
- skeylen = subkeylength;
769
+ _bysubkeys = k2hbindup(psubkeys, subkeylength);
770
+ _skeylen = subkeylength;
722
771
  }
723
772
  }
724
773
 
725
774
  ~SetAllWorker()
726
775
  {
727
- K2H_Free(bysubkeys);
776
+ if(_callbackRef){
777
+ _callbackRef.Unref();
778
+ _callbackRef.Reset();
779
+ }
780
+ K2H_Free(_bysubkeys);
728
781
  }
729
782
 
730
- void Execute()
783
+ // Run on worker thread
784
+ void Execute() override
731
785
  {
732
- if(!pslaveobj && !is_set_conf){
786
+ if(!_slaveobj.GetChmCntrlObject() && _conf.empty()){
733
787
  // onetime connection mode needs configuration
734
- this->SetErrorMessage("No configuration is associated to async worker");
788
+ SetError("No configuration is associated to async worker");
735
789
  return;
736
790
  }
737
- if(!is_key_set){
738
- this->SetErrorMessage("Specified key is empty(null)");
791
+ if(_strkey.empty()){
792
+ SetError("Specified key is empty(null)");
739
793
  return;
740
794
  }
741
795
 
742
796
  // work
743
797
  bool result = false;
744
798
  dkcres_type_t rescode = DKC_NORESTYPE;
745
-
746
- // cppcheck-suppress unmatchedSuppression
747
- // cppcheck-suppress knownConditionTrueFalse
748
- if(is_pass_set && 0 < expire){
799
+ if(!_strpass.empty() && 0 < _expire){
749
800
  // set value with passphrase and expire, then the operation is separated.
750
801
  K2hdkcComSet* pComObj;
751
- if(!pslaveobj){
752
- pComObj = GetOtSlaveK2hdkcComSet(conf.c_str(), ctlport, (cuk.empty() ? NULL : cuk.c_str()), auto_rejoin, no_giveup_rejoin);
802
+ if(!_slaveobj.GetChmCntrlObject()){
803
+ pComObj = GetOtSlaveK2hdkcComSet(_conf.c_str(), _ctlport, (_cuk.empty() ? NULL : _cuk.c_str()), _auto_rejoin, _no_giveup_rejoin);
753
804
  }else{
754
- pComObj = GetPmSlaveK2hdkcComSet(pslaveobj);
805
+ pComObj = GetPmSlaveK2hdkcComSet(&_slaveobj);
755
806
  }
756
- // cppcheck-suppress unmatchedSuppression
757
- // cppcheck-suppress knownConditionTrueFalse
758
807
  if(!pComObj){
759
- this->SetErrorMessage("Internal error: Could not create command object.");
808
+ SetError("Internal error: Could not create command object.");
760
809
  return;
761
810
  }
762
811
 
763
812
  // set value to key
764
- // cppcheck-suppress unmatchedSuppression
765
- // cppcheck-suppress knownConditionTrueFalse
766
- result = pComObj->CommandSend(reinterpret_cast<const unsigned char*>(strkey.c_str()), strkey.length() + 1, (is_val_set ? reinterpret_cast<const unsigned char*>(strval.c_str()) : NULL), (is_val_set ? strval.length() + 1 : 0), false, (is_pass_set ? strpass.c_str() : NULL), &expire, &rescode);
813
+ result = pComObj->CommandSend(reinterpret_cast<const unsigned char*>(_strkey.c_str()), _strkey.length() + 1, (_strval.empty() ? NULL : reinterpret_cast<const unsigned char*>(_strval.c_str())), (_strval.empty() ? 0 : _strval.length() + 1), false, _strpass.c_str(), &_expire, &rescode);
767
814
  DKC_DELETE(pComObj);
768
815
 
769
816
  // set subkeys
770
- if(result && bysubkeys && 0UL < skeylen){
771
-
817
+ if(result && _bysubkeys && 0UL < _skeylen){
772
818
  K2hdkcComSetSubkeys* pSubComObj;
773
- if(!pslaveobj){
774
- pSubComObj = GetOtSlaveK2hdkcComSetSubkeys(conf.c_str(), ctlport, (cuk.empty() ? NULL : cuk.c_str()), auto_rejoin, no_giveup_rejoin);
819
+ if(!_slaveobj.GetChmCntrlObject()){
820
+ pSubComObj = GetOtSlaveK2hdkcComSetSubkeys(_conf.c_str(), _ctlport, (_cuk.empty() ? NULL : _cuk.c_str()), _auto_rejoin, _no_giveup_rejoin);
775
821
  }else{
776
- pSubComObj = GetPmSlaveK2hdkcComSetSubkeys(pslaveobj);
822
+ pSubComObj = GetPmSlaveK2hdkcComSetSubkeys(&_slaveobj);
777
823
  }
778
824
  if(!pSubComObj){
779
- this->SetErrorMessage("Internal error: Could not create command object.");
825
+ SetError("Internal error: Could not create command object.");
780
826
  return;
781
827
  }
782
828
 
783
829
  // set subkeys to key
784
- result = pSubComObj->CommandSend(reinterpret_cast<const unsigned char*>(strkey.c_str()), strkey.length() + 1, bysubkeys, skeylen, &rescode);
830
+ result = pSubComObj->CommandSend(reinterpret_cast<const unsigned char*>(_strkey.c_str()), _strkey.length() + 1, _bysubkeys, _skeylen, &rescode);
785
831
  DKC_DELETE(pSubComObj);
786
832
  }
787
833
 
788
834
  }else{
789
835
  // no passphrase and no expire, then one action
790
836
  K2hdkcComSetAll* pComObj;
791
- if(!pslaveobj){
792
- pComObj = GetOtSlaveK2hdkcComSetAll(conf.c_str(), ctlport, (cuk.empty() ? NULL : cuk.c_str()), auto_rejoin, no_giveup_rejoin);
837
+ if(!_slaveobj.GetChmCntrlObject()){
838
+ pComObj = GetOtSlaveK2hdkcComSetAll(_conf.c_str(), _ctlport, (_cuk.empty() ? NULL : _cuk.c_str()), _auto_rejoin, _no_giveup_rejoin);
793
839
  }else{
794
- pComObj = GetPmSlaveK2hdkcComSetAll(pslaveobj);
840
+ pComObj = GetPmSlaveK2hdkcComSetAll(&_slaveobj);
795
841
  }
796
842
  if(!pComObj){
797
- this->SetErrorMessage("Internal error: Could not create command object.");
843
+ SetError("Internal error: Could not create command object.");
798
844
  return;
799
845
  }
800
846
  // set value and subkeys
801
- result = pComObj->CommandSend(reinterpret_cast<const unsigned char*>(strkey.c_str()), strkey.length() + 1, (is_val_set ? reinterpret_cast<const unsigned char*>(strval.c_str()) : NULL), (is_val_set ? strval.length() + 1 : 0), bysubkeys, skeylen, NULL, 0UL, &rescode);
847
+ result = pComObj->CommandSend(reinterpret_cast<const unsigned char*>(_strkey.c_str()), _strkey.length() + 1, (_strval.empty() ? NULL : reinterpret_cast<const unsigned char*>(_strval.c_str())), (_strval.empty() ? 0 : _strval.length() + 1), _bysubkeys, _skeylen, NULL, 0UL, &rescode);
802
848
  DKC_DELETE(pComObj);
803
849
  }
804
850
  if(!result){
805
- this->SetErrorMessage("Failed to set value/subkeys into key.");
851
+ SetError("Failed to set value/subkeys into key.");
806
852
  }
807
853
  }
808
854
 
809
- void HandleOKCallback()
855
+ // handler for success
856
+ void OnOK() override
810
857
  {
811
- Nan::HandleScope scope;
812
- const int argc = 1;
813
- v8::Local<v8::Value> argv[argc] = { Nan::Null() };
858
+ Napi::Env env = Env();
859
+ Napi::HandleScope scope(env);
814
860
 
815
- if(callback){
816
- callback->Call(argc, argv);
861
+ if(!_callbackRef.IsEmpty()){
862
+ _callbackRef.Value().Call({ env.Null() });
817
863
  }else{
818
- Nan::ThrowSyntaxError("Internal error in async worker");
819
- return;
864
+ Napi::TypeError::New(env, "Internal error in async worker");
820
865
  }
821
866
  }
822
867
 
823
- void HandleErrorCallback()
824
- {
825
- Nan::HandleScope scope;
826
- const int argc = 1;
827
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
868
+ // handler for failure (by calling SetError)
869
+ void OnError(const Napi::Error& err) override
870
+ {
871
+ Napi::Env env = Env();
872
+ Napi::HandleScope scope(env);
828
873
 
829
- if(callback){
830
- callback->Call(argc, argv);
874
+ // The first argument is the error message.
875
+ if(!_callbackRef.IsEmpty()){
876
+ _callbackRef.Value().Call({ Napi::String::New(env, err.Value().ToString().Utf8Value()) });
831
877
  }else{
832
- Nan::ThrowSyntaxError("Internal error in async worker");
833
- return;
878
+ // Throw error
879
+ err.ThrowAsJavaScriptException();
834
880
  }
835
- }
881
+ }
836
882
 
837
883
  private:
838
- K2hdkcSlave* pslaveobj;
839
-
840
- bool is_set_conf;
841
- std::string conf;
842
- int16_t ctlport;
843
- std::string cuk;
844
- bool auto_rejoin;
845
- bool no_giveup_rejoin;
846
-
847
- bool is_key_set;
848
- std::string strkey;
849
- bool is_val_set;
850
- std::string strval;
851
- unsigned char* bysubkeys;
852
- size_t skeylen;
853
- bool is_pass_set;
854
- std::string strpass;
855
- time_t expire;
884
+ Napi::FunctionReference _callbackRef;
885
+ K2hdkcSlave& _slaveobj;
886
+ std::string _conf;
887
+ int16_t _ctlport;
888
+ std::string _cuk;
889
+ bool _auto_rejoin;
890
+ bool _no_giveup_rejoin;
891
+
892
+ std::string _strkey;
893
+ std::string _strval;
894
+ unsigned char* _bysubkeys;
895
+ size_t _skeylen;
896
+ std::string _strpass;
897
+ time_t _expire;
856
898
  };
857
899
 
858
900
  //---------------------------------------------------------
859
901
  // RemoveWorker class
860
902
  //
861
- // Constructor: constructor(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pkey, bool is_del_subkeys)
903
+ // Constructor: constructor(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& key, bool is_del_subkeys)
862
904
  // Callback function: function(string error)
863
905
  //
864
906
  //---------------------------------------------------------
865
- class RemoveWorker : public Nan::AsyncWorker
907
+ class RemoveWorker : public Napi::AsyncWorker
866
908
  {
867
909
  public:
868
- RemoveWorker(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, const char* inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pkey, bool is_del_subkeys) :
869
- Nan::AsyncWorker(callback), pslaveobj(pobj),
870
- is_set_conf(NULL != configuration), conf(configuration ? configuration : ""), ctlport(control_port), cuk(inputcuk ? inputcuk : ""), auto_rejoin(is_auto_rejoin), no_giveup_rejoin(is_nogiveup_rejoin),
871
- is_key_set(NULL != pkey), strkey(pkey ? pkey : ""), is_subkeys(is_del_subkeys)
872
- {}
910
+ RemoveWorker(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& key, bool is_del_subkeys) :
911
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)),
912
+ _slaveobj(slaveobj), _conf(configuration), _ctlport(control_port), _cuk(inputcuk), _auto_rejoin(is_auto_rejoin), _no_giveup_rejoin(is_nogiveup_rejoin), _strkey(key), _is_subkeys(is_del_subkeys)
913
+ {
914
+ _callbackRef.Ref();
915
+ }
873
916
 
874
- ~RemoveWorker() {}
917
+ ~RemoveWorker() override
918
+ {
919
+ if(_callbackRef){
920
+ _callbackRef.Unref();
921
+ _callbackRef.Reset();
922
+ }
923
+ }
875
924
 
876
- void Execute()
925
+ // Run on worker thread
926
+ void Execute() override
877
927
  {
878
- if(!pslaveobj && !is_set_conf){
928
+ if(!_slaveobj.GetChmCntrlObject() && _conf.empty()){
879
929
  // onetime connection mode needs configuration
880
- this->SetErrorMessage("No configuration is associated to async worker");
930
+ SetError("No configuration is associated to async worker");
881
931
  return;
882
932
  }
883
- if(!is_key_set){
884
- this->SetErrorMessage("Specified key is empty(null)");
933
+ if(_strkey.empty()){
934
+ SetError("Specified key is empty(null)");
885
935
  return;
886
936
  }
887
937
 
888
938
  // work
889
939
  K2hdkcComDel* pComObj;
890
- if(!pslaveobj){
891
- pComObj = GetOtSlaveK2hdkcComDel(conf.c_str(), ctlport, (cuk.empty() ? NULL : cuk.c_str()), auto_rejoin, no_giveup_rejoin);
940
+ if(!_slaveobj.GetChmCntrlObject()){
941
+ pComObj = GetOtSlaveK2hdkcComDel(_conf.c_str(), _ctlport, (_cuk.empty() ? NULL : _cuk.c_str()), _auto_rejoin, _no_giveup_rejoin);
892
942
  }else{
893
- pComObj = GetPmSlaveK2hdkcComDel(pslaveobj);
943
+ pComObj = GetPmSlaveK2hdkcComDel(&_slaveobj);
894
944
  }
895
945
  if(!pComObj){
896
- this->SetErrorMessage("Internal error: Could not create command object.");
946
+ SetError("Internal error: Could not create command object.");
897
947
  return;
898
948
  }
899
949
 
900
950
  // remove key
901
951
  dkcres_type_t rescode = DKC_NORESTYPE;
902
- if(!pComObj->CommandSend(reinterpret_cast<const unsigned char*>(strkey.c_str()), strkey.length() + 1, is_subkeys, true, &rescode)){
903
- this->SetErrorMessage("Failed to remove key.");
952
+ if(!pComObj->CommandSend(reinterpret_cast<const unsigned char*>(_strkey.c_str()), _strkey.length() + 1, _is_subkeys, true, &rescode)){
953
+ SetError("Failed to remove key.");
904
954
  }
905
955
  DKC_DELETE(pComObj);
906
956
  }
907
957
 
908
- void HandleOKCallback()
958
+ // handler for success
959
+ void OnOK() override
909
960
  {
910
- Nan::HandleScope scope;
911
- const int argc = 1;
912
- v8::Local<v8::Value> argv[argc] = { Nan::Null() };
961
+ Napi::Env env = Env();
962
+ Napi::HandleScope scope(env);
913
963
 
914
- if(callback){
915
- callback->Call(argc, argv);
964
+ if(!_callbackRef.IsEmpty()){
965
+ _callbackRef.Value().Call({ env.Null() });
916
966
  }else{
917
- Nan::ThrowSyntaxError("Internal error in async worker");
918
- return;
967
+ Napi::TypeError::New(env, "Internal error in async worker");
919
968
  }
920
969
  }
921
970
 
922
- void HandleErrorCallback()
923
- {
924
- Nan::HandleScope scope;
925
- const int argc = 1;
926
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
971
+ // handler for failure (by calling SetError)
972
+ void OnError(const Napi::Error& err) override
973
+ {
974
+ Napi::Env env = Env();
975
+ Napi::HandleScope scope(env);
927
976
 
928
- if(callback){
929
- callback->Call(argc, argv);
977
+ // The first argument is the error message.
978
+ if(!_callbackRef.IsEmpty()){
979
+ _callbackRef.Value().Call({ Napi::String::New(env, err.Value().ToString().Utf8Value()) });
930
980
  }else{
931
- Nan::ThrowSyntaxError("Internal error in async worker");
932
- return;
981
+ // Throw error
982
+ err.ThrowAsJavaScriptException();
933
983
  }
934
- }
984
+ }
935
985
 
936
986
  private:
937
- K2hdkcSlave* pslaveobj;
938
-
939
- bool is_set_conf;
940
- std::string conf;
941
- int16_t ctlport;
942
- std::string cuk;
943
- bool auto_rejoin;
944
- bool no_giveup_rejoin;
945
-
946
- bool is_key_set;
947
- std::string strkey;
948
- bool is_subkeys;
987
+ Napi::FunctionReference _callbackRef;
988
+ K2hdkcSlave& _slaveobj;
989
+ std::string _conf;
990
+ int16_t _ctlport;
991
+ std::string _cuk;
992
+ bool _auto_rejoin;
993
+ bool _no_giveup_rejoin;
994
+
995
+ std::string _strkey;
996
+ bool _is_subkeys;
949
997
  };
950
998
 
951
999
  //---------------------------------------------------------
952
1000
  // RenameWorker class
953
1001
  //
954
- // Constructor: constructor(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* poldkey, const char* pnewkey, const char* pparentkey, bool is_check_attr, const char* ppass, const time_t* pexpire)
1002
+ // Constructor: constructor(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& oldkey, const std::string& newkey, const std::string& parentkey, bool is_check_attr, const std::string& pass, const time_t input_expire)
955
1003
  // Callback function: function(string error)
956
1004
  //
957
1005
  //---------------------------------------------------------
958
- class RenameWorker : public Nan::AsyncWorker
1006
+ class RenameWorker : public Napi::AsyncWorker
959
1007
  {
960
1008
  public:
961
- RenameWorker(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, const char* inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* poldkey, const char* pnewkey, const char* pparentkey, bool is_check_attr, const char* ppass, const time_t* pexpire) :
962
- Nan::AsyncWorker(callback), pslaveobj(pobj),
963
- is_set_conf(NULL != configuration), conf(configuration ? configuration : ""), ctlport(control_port), cuk(inputcuk ? inputcuk : ""), auto_rejoin(is_auto_rejoin), no_giveup_rejoin(is_nogiveup_rejoin),
964
- is_old_set(NULL != poldkey), strold(poldkey ? poldkey : ""), is_new_set(NULL != pnewkey), strnew(pnewkey ? pnewkey : ""), is_parent_set(NULL != pparentkey), strparent(pparentkey ? pparentkey : ""), attrchk(is_check_attr), is_pass_set(NULL != ppass), strpass(ppass ? ppass : ""), expire(pexpire ? *pexpire : 0)
965
- {}
1009
+ RenameWorker(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& oldkey, const std::string& newkey, const std::string& parentkey, bool is_check_attr, const std::string& pass, const time_t input_expire) :
1010
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)),
1011
+ _slaveobj(slaveobj), _conf(configuration), _ctlport(control_port), _cuk(inputcuk), _auto_rejoin(is_auto_rejoin), _no_giveup_rejoin(is_nogiveup_rejoin), _strold(oldkey), _strnew(newkey), _strparent(parentkey), _attrchk(is_check_attr), _strpass(pass), _expire(input_expire)
1012
+ {
1013
+ _callbackRef.Ref();
1014
+ }
966
1015
 
967
- ~RenameWorker() {}
1016
+ ~RenameWorker() override
1017
+ {
1018
+ if(_callbackRef){
1019
+ _callbackRef.Unref();
1020
+ _callbackRef.Reset();
1021
+ }
1022
+ }
968
1023
 
969
- void Execute()
1024
+ // Run on worker thread
1025
+ void Execute() override
970
1026
  {
971
- if(!pslaveobj && !is_set_conf){
1027
+ if(!_slaveobj.GetChmCntrlObject() && _conf.empty()){
972
1028
  // onetime connection mode needs configuration
973
- this->SetErrorMessage("No configuration is associated to async worker");
1029
+ SetError("No configuration is associated to async worker");
974
1030
  return;
975
1031
  }
976
- if(!is_old_set || !is_new_set){
977
- this->SetErrorMessage("Specified source(old) key or destination(new) key name is empty(null)");
1032
+ if(_strold.empty() || _strnew.empty()){
1033
+ SetError("Specified source(old) key or destination(new) key name is empty(null)");
978
1034
  return;
979
1035
  }
980
1036
 
981
1037
  // work
982
1038
  K2hdkcComRen* pComObj;
983
- if(!pslaveobj){
984
- pComObj = GetOtSlaveK2hdkcComRen(conf.c_str(), ctlport, (cuk.empty() ? NULL : cuk.c_str()), auto_rejoin, no_giveup_rejoin);
1039
+ if(!_slaveobj.GetChmCntrlObject()){
1040
+ pComObj = GetOtSlaveK2hdkcComRen(_conf.c_str(), _ctlport, (_cuk.empty() ? NULL : _cuk.c_str()), _auto_rejoin, _no_giveup_rejoin);
985
1041
  }else{
986
- pComObj = GetPmSlaveK2hdkcComRen(pslaveobj);
1042
+ pComObj = GetPmSlaveK2hdkcComRen(&_slaveobj);
987
1043
  }
988
1044
  if(!pComObj){
989
- this->SetErrorMessage("Internal error: Could not create command object.");
1045
+ SetError("Internal error: Could not create command object.");
990
1046
  return;
991
1047
  }
992
1048
 
993
1049
  // rename key
994
1050
  dkcres_type_t rescode = DKC_NORESTYPE;
995
- if(!pComObj->CommandSend(reinterpret_cast<const unsigned char*>(strold.c_str()), strold.length() + 1, reinterpret_cast<const unsigned char*>(strnew.c_str()), strnew.length() + 1, (is_parent_set ? reinterpret_cast<const unsigned char*>(strparent.c_str()) : NULL), (is_parent_set ? strparent.length() + 1 : 0), attrchk, (is_pass_set ? strpass.c_str() : NULL), (expire > 0 ? &expire : NULL), &rescode)){
996
- this->SetErrorMessage("Failed to rename key.");
1051
+ if(!pComObj->CommandSend(reinterpret_cast<const unsigned char*>(_strold.c_str()), _strold.length() + 1, reinterpret_cast<const unsigned char*>(_strnew.c_str()), _strnew.length() + 1, (_strparent.empty() ? NULL : reinterpret_cast<const unsigned char*>(_strparent.c_str())), (_strparent.empty() ? 0 : _strparent.length() + 1), _attrchk, (_strpass.empty() ? NULL : _strpass.c_str()), (_expire > 0 ? &_expire : NULL), &rescode)){
1052
+ SetError("Failed to rename key.");
997
1053
  }
998
1054
  DKC_DELETE(pComObj);
999
1055
  }
1000
1056
 
1001
- void HandleOKCallback()
1057
+ // handler for success
1058
+ void OnOK() override
1002
1059
  {
1003
- Nan::HandleScope scope;
1004
- const int argc = 1;
1005
- v8::Local<v8::Value> argv[argc] = { Nan::Null() };
1060
+ Napi::Env env = Env();
1061
+ Napi::HandleScope scope(env);
1006
1062
 
1007
- if(callback){
1008
- callback->Call(argc, argv);
1063
+ if(!_callbackRef.IsEmpty()){
1064
+ _callbackRef.Value().Call({ env.Null() });
1009
1065
  }else{
1010
- Nan::ThrowSyntaxError("Internal error in async worker");
1011
- return;
1066
+ Napi::TypeError::New(env, "Internal error in async worker");
1012
1067
  }
1013
1068
  }
1014
1069
 
1015
- void HandleErrorCallback()
1016
- {
1017
- Nan::HandleScope scope;
1018
- const int argc = 1;
1019
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
1070
+ // handler for failure (by calling SetError)
1071
+ void OnError(const Napi::Error& err) override
1072
+ {
1073
+ Napi::Env env = Env();
1074
+ Napi::HandleScope scope(env);
1020
1075
 
1021
- if(callback){
1022
- callback->Call(argc, argv);
1076
+ // The first argument is the error message.
1077
+ if(!_callbackRef.IsEmpty()){
1078
+ _callbackRef.Value().Call({ Napi::String::New(env, err.Value().ToString().Utf8Value()) });
1023
1079
  }else{
1024
- Nan::ThrowSyntaxError("Internal error in async worker");
1025
- return;
1080
+ // Throw error
1081
+ err.ThrowAsJavaScriptException();
1026
1082
  }
1027
- }
1083
+ }
1028
1084
 
1029
1085
  private:
1030
- K2hdkcSlave* pslaveobj;
1031
-
1032
- bool is_set_conf;
1033
- std::string conf;
1034
- int16_t ctlport;
1035
- std::string cuk;
1036
- bool auto_rejoin;
1037
- bool no_giveup_rejoin;
1038
-
1039
- bool is_old_set;
1040
- std::string strold;
1041
- bool is_new_set;
1042
- std::string strnew;
1043
- bool is_parent_set;
1044
- std::string strparent;
1045
- bool attrchk;
1046
- bool is_pass_set;
1047
- std::string strpass;
1048
- time_t expire;
1086
+ Napi::FunctionReference _callbackRef;
1087
+ K2hdkcSlave& _slaveobj;
1088
+ std::string _conf;
1089
+ int16_t _ctlport;
1090
+ std::string _cuk;
1091
+ bool _auto_rejoin;
1092
+ bool _no_giveup_rejoin;
1093
+
1094
+ std::string _strold;
1095
+ std::string _strnew;
1096
+ std::string _strparent;
1097
+ bool _attrchk;
1098
+ std::string _strpass;
1099
+ time_t _expire;
1049
1100
  };
1050
1101
 
1051
1102
  //---------------------------------------------------------
1052
1103
  // QueuePushWorker class
1053
1104
  //
1054
- // Constructor: constructor(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pprefix, const char* pkey, const char* pval, bool is_fifo_type, bool is_check_attr, const char* ppass, const time_t* pexpire)
1105
+ // Constructor: constructor(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& prefix, const std::string& key, const std::string& val, bool is_fifo_type, bool is_check_attr, const std::string& pass, const time_t input_expire)
1055
1106
  // Callback function: function(string error)
1056
1107
  //
1057
1108
  //---------------------------------------------------------
1058
- class QueuePushWorker : public Nan::AsyncWorker
1109
+ class QueuePushWorker : public Napi::AsyncWorker
1059
1110
  {
1060
1111
  public:
1061
- QueuePushWorker(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, const char* inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pprefix, const char* pkey, const char* pval, bool is_fifo_type, bool is_check_attr, const char* ppass, const time_t* pexpire) :
1062
- Nan::AsyncWorker(callback), pslaveobj(pobj),
1063
- is_set_conf(NULL != configuration), conf(configuration ? configuration : ""), ctlport(control_port), cuk(inputcuk ? inputcuk : ""), auto_rejoin(is_auto_rejoin), no_giveup_rejoin(is_nogiveup_rejoin),
1064
- is_prefix_set(NULL != pprefix), strprefix(pprefix ? pprefix : ""), is_key_set(NULL != pkey), strkey(pkey ? pkey : ""), is_val_set(NULL != pval), strval(pval ? pval : ""), is_fifo(is_fifo_type), attrchk(is_check_attr), is_pass_set(NULL != ppass), strpass(ppass ? ppass : ""), expire(pexpire ? *pexpire : 0)
1065
- {}
1112
+ QueuePushWorker(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& prefix, const std::string& key, const std::string& val, bool is_fifo_type, bool is_check_attr, const std::string& pass, const time_t input_expire) :
1113
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)),
1114
+ _slaveobj(slaveobj), _conf(configuration), _ctlport(control_port), _cuk(inputcuk), _auto_rejoin(is_auto_rejoin), _no_giveup_rejoin(is_nogiveup_rejoin), _strprefix(prefix), _strkey(key), _strval(val), _is_fifo(is_fifo_type), _attrchk(is_check_attr), _strpass(pass), _expire(input_expire)
1115
+ {
1116
+ _callbackRef.Ref();
1117
+ }
1066
1118
 
1067
- ~QueuePushWorker() {}
1119
+ ~QueuePushWorker() override
1120
+ {
1121
+ if(_callbackRef){
1122
+ _callbackRef.Unref();
1123
+ _callbackRef.Reset();
1124
+ }
1125
+ }
1068
1126
 
1069
- void Execute()
1127
+ // Run on worker thread
1128
+ void Execute() override
1070
1129
  {
1071
- if(!pslaveobj && !is_set_conf){
1130
+ if(!_slaveobj.GetChmCntrlObject() && _conf.empty()){
1072
1131
  // onetime connection mode needs configuration
1073
- this->SetErrorMessage("No configuration is associated to async worker");
1132
+ SetError("No configuration is associated to async worker");
1074
1133
  return;
1075
1134
  }
1076
- if(!is_prefix_set || !is_val_set){
1077
- this->SetErrorMessage("Specified prefix or value is empty(null)");
1135
+ if(_strprefix.empty() || _strval.empty()){
1136
+ SetError("Specified prefix or value is empty(null)");
1078
1137
  return;
1079
1138
  }
1080
1139
 
1081
1140
  // work
1082
1141
  K2hdkcComQPush* pComObj;
1083
- if(!pslaveobj){
1084
- pComObj = GetOtSlaveK2hdkcComQPush(conf.c_str(), ctlport, (cuk.empty() ? NULL : cuk.c_str()), auto_rejoin, no_giveup_rejoin);
1142
+ if(!_slaveobj.GetChmCntrlObject()){
1143
+ pComObj = GetOtSlaveK2hdkcComQPush(_conf.c_str(), _ctlport, (_cuk.empty() ? NULL : _cuk.c_str()), _auto_rejoin, _no_giveup_rejoin);
1085
1144
  }else{
1086
- pComObj = GetPmSlaveK2hdkcComQPush(pslaveobj);
1145
+ pComObj = GetPmSlaveK2hdkcComQPush(&_slaveobj);
1087
1146
  }
1088
1147
  if(!pComObj){
1089
- this->SetErrorMessage("Internal error: Could not create command object.");
1148
+ SetError("Internal error: Could not create command object.");
1090
1149
  return;
1091
1150
  }
1092
1151
 
1093
1152
  dkcres_type_t rescode = DKC_NORESTYPE;
1094
1153
  bool result = false;
1095
- if(is_key_set){
1154
+ if(!_strkey.empty()){
1096
1155
  // key queue
1097
- result = pComObj->KeyQueueCommandSend(reinterpret_cast<const unsigned char*>(strprefix.c_str()), strprefix.length() + 1, reinterpret_cast<const unsigned char*>(strkey.c_str()), strkey.length() + 1, reinterpret_cast<const unsigned char*>(strval.c_str()), strval.length() + 1, is_fifo, NULL, 0UL, attrchk, (is_pass_set ? strpass.c_str() : NULL), (expire > 0 ? &expire : NULL), &rescode);
1156
+ result = pComObj->KeyQueueCommandSend(reinterpret_cast<const unsigned char*>(_strprefix.c_str()), _strprefix.length() + 1, reinterpret_cast<const unsigned char*>(_strkey.c_str()), _strkey.length() + 1, reinterpret_cast<const unsigned char*>(_strval.c_str()), _strval.length() + 1, _is_fifo, NULL, 0UL, _attrchk, (_strpass.empty() ? NULL : _strpass.c_str()), (_expire > 0 ? &_expire : NULL), &rescode);
1098
1157
  }else{
1099
1158
  // queue
1100
- result = pComObj->QueueCommandSend(reinterpret_cast<const unsigned char*>(strprefix.c_str()), strprefix.length() + 1, reinterpret_cast<const unsigned char*>(strval.c_str()), strval.length() + 1, is_fifo, NULL, 0UL, attrchk, (is_pass_set ? strpass.c_str() : NULL), (expire > 0 ? &expire : NULL), &rescode);
1159
+ result = pComObj->QueueCommandSend(reinterpret_cast<const unsigned char*>(_strprefix.c_str()), _strprefix.length() + 1, reinterpret_cast<const unsigned char*>(_strval.c_str()), _strval.length() + 1, _is_fifo, NULL, 0UL, _attrchk, (_strpass.empty() ? NULL : _strpass.c_str()), (_expire > 0 ? &_expire : NULL), &rescode);
1101
1160
  }
1102
1161
  if(!result){
1103
- this->SetErrorMessage("Failed to push queue.");
1162
+ SetError("Failed to push queue.");
1104
1163
  }
1105
1164
  DKC_DELETE(pComObj);
1106
1165
  }
1107
1166
 
1108
- void HandleOKCallback()
1167
+ // handler for success
1168
+ void OnOK() override
1109
1169
  {
1110
- Nan::HandleScope scope;
1111
- const int argc = 1;
1112
- v8::Local<v8::Value> argv[argc] = { Nan::Null() };
1170
+ Napi::Env env = Env();
1171
+ Napi::HandleScope scope(env);
1113
1172
 
1114
- if(callback){
1115
- callback->Call(argc, argv);
1173
+ if(!_callbackRef.IsEmpty()){
1174
+ _callbackRef.Value().Call({ env.Null() });
1116
1175
  }else{
1117
- Nan::ThrowSyntaxError("Internal error in async worker");
1118
- return;
1176
+ Napi::TypeError::New(env, "Internal error in async worker");
1119
1177
  }
1120
1178
  }
1121
1179
 
1122
- void HandleErrorCallback()
1123
- {
1124
- Nan::HandleScope scope;
1125
- const int argc = 1;
1126
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
1180
+ // handler for failure (by calling SetError)
1181
+ void OnError(const Napi::Error& err) override
1182
+ {
1183
+ Napi::Env env = Env();
1184
+ Napi::HandleScope scope(env);
1127
1185
 
1128
- if(callback){
1129
- callback->Call(argc, argv);
1186
+ // The first argument is the error message.
1187
+ if(!_callbackRef.IsEmpty()){
1188
+ _callbackRef.Value().Call({ Napi::String::New(env, err.Value().ToString().Utf8Value()) });
1130
1189
  }else{
1131
- Nan::ThrowSyntaxError("Internal error in async worker");
1132
- return;
1190
+ // Throw error
1191
+ err.ThrowAsJavaScriptException();
1133
1192
  }
1134
- }
1193
+ }
1135
1194
 
1136
1195
  private:
1137
- K2hdkcSlave* pslaveobj;
1138
-
1139
- bool is_set_conf;
1140
- std::string conf;
1141
- int16_t ctlport;
1142
- std::string cuk;
1143
- bool auto_rejoin;
1144
- bool no_giveup_rejoin;
1145
-
1146
- bool is_prefix_set;
1147
- std::string strprefix;
1148
- bool is_key_set;
1149
- std::string strkey;
1150
- bool is_val_set;
1151
- std::string strval;
1152
- bool is_fifo;
1153
- bool attrchk;
1154
- bool is_pass_set;
1155
- std::string strpass;
1156
- time_t expire;
1196
+ Napi::FunctionReference _callbackRef;
1197
+ K2hdkcSlave& _slaveobj;
1198
+ std::string _conf;
1199
+ int16_t _ctlport;
1200
+ std::string _cuk;
1201
+ bool _auto_rejoin;
1202
+ bool _no_giveup_rejoin;
1203
+
1204
+ std::string _strprefix;
1205
+ std::string _strkey;
1206
+ std::string _strval;
1207
+ bool _is_fifo;
1208
+ bool _attrchk;
1209
+ std::string _strpass;
1210
+ time_t _expire;
1157
1211
  };
1158
1212
 
1159
1213
  //---------------------------------------------------------
1160
1214
  // QueuePopWorker class
1161
1215
  //
1162
- // Constructor: constructor(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pprefix, bool is_fifo_type, bool is_key_queue_type, const char* ppass)
1216
+ // Constructor: constructor(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& prefix, bool is_fifo_type, bool is_key_queue_type, const std::string& pass)
1163
1217
  // Callback function: function(string error[[, string key], string value])
1164
1218
  //
1165
1219
  //---------------------------------------------------------
1166
- class QueuePopWorker : public Nan::AsyncWorker
1220
+ class QueuePopWorker : public Napi::AsyncWorker
1167
1221
  {
1168
1222
  public:
1169
- QueuePopWorker(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, const char* inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pprefix, bool is_fifo_type, bool is_key_queue_type, const char* ppass) :
1170
- Nan::AsyncWorker(callback), pslaveobj(pobj),
1171
- is_set_conf(NULL != configuration), conf(configuration ? configuration : ""), ctlport(control_port), cuk(inputcuk ? inputcuk : ""), auto_rejoin(is_auto_rejoin), no_giveup_rejoin(is_nogiveup_rejoin),
1172
- is_prefix_set(NULL != pprefix), strprefix(pprefix ? pprefix : ""), is_fifo(is_fifo_type), is_key_queue(is_key_queue_type), is_pass_set(NULL != ppass), strpass(ppass ? ppass : ""),
1173
- is_res_key_set(false), strreskey(""), is_res_val_set(false), strresval("")
1174
- {}
1223
+ QueuePopWorker(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& prefix, bool is_fifo_type, bool is_key_queue_type, const std::string& pass) :
1224
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)),
1225
+ _slaveobj(slaveobj), _conf(configuration), _ctlport(control_port), _cuk(inputcuk), _auto_rejoin(is_auto_rejoin), _no_giveup_rejoin(is_nogiveup_rejoin), _strprefix(prefix), _is_fifo(is_fifo_type), _is_key_queue(is_key_queue_type), _strpass(pass), _is_res_key_set(false), _strreskey(""), _is_res_val_set(false), _strresval("")
1226
+ {
1227
+ _callbackRef.Ref();
1228
+ }
1175
1229
 
1176
- ~QueuePopWorker() {}
1230
+ ~QueuePopWorker() override
1231
+ {
1232
+ if(_callbackRef){
1233
+ _callbackRef.Unref();
1234
+ _callbackRef.Reset();
1235
+ }
1236
+ }
1177
1237
 
1178
- void Execute()
1238
+ // Run on worker thread
1239
+ void Execute() override
1179
1240
  {
1180
- if(!pslaveobj && !is_set_conf){
1241
+ if(!_slaveobj.GetChmCntrlObject() && _conf.empty()){
1181
1242
  // onetime connection mode needs configuration
1182
- this->SetErrorMessage("No configuration is associated to async worker");
1243
+ SetError("No configuration is associated to async worker");
1183
1244
  return;
1184
1245
  }
1185
- if(!is_prefix_set){
1186
- this->SetErrorMessage("Specified prefix is empty(null)");
1246
+ if(_strprefix.empty()){
1247
+ SetError("Specified prefix is empty(null)");
1187
1248
  return;
1188
1249
  }
1189
1250
 
1190
1251
  // work
1191
1252
  K2hdkcComQPop* pComObj;
1192
- if(!pslaveobj){
1193
- pComObj = GetOtSlaveK2hdkcComQPop(conf.c_str(), ctlport, (cuk.empty() ? NULL : cuk.c_str()), auto_rejoin, no_giveup_rejoin);
1253
+ if(!_slaveobj.GetChmCntrlObject()){
1254
+ pComObj = GetOtSlaveK2hdkcComQPop(_conf.c_str(), _ctlport, (_cuk.empty() ? NULL : _cuk.c_str()), _auto_rejoin, _no_giveup_rejoin);
1194
1255
  }else{
1195
- pComObj = GetPmSlaveK2hdkcComQPop(pslaveobj);
1256
+ pComObj = GetPmSlaveK2hdkcComQPop(&_slaveobj);
1196
1257
  }
1197
1258
  if(!pComObj){
1198
- this->SetErrorMessage("Internal error: Could not create command object.");
1259
+ SetError("Internal error: Could not create command object.");
1199
1260
  return;
1200
1261
  }
1201
1262
 
1202
1263
  dkcres_type_t rescode = DKC_NORESTYPE;
1203
1264
  bool result = false;
1204
- if(is_key_queue){
1265
+ if(_is_key_queue){
1205
1266
  // key queue
1206
1267
  const unsigned char* pkeytmp = NULL;
1207
1268
  size_t keytmplen = 0L;
1208
1269
  const unsigned char* pvaltmp = NULL;
1209
1270
  size_t valtmplen = 0L;
1210
- result = pComObj->KeyQueueCommandSend(reinterpret_cast<const unsigned char*>(strprefix.c_str()), strprefix.length() + 1, is_fifo, true, (is_pass_set ? strpass.c_str() : NULL), &pkeytmp, &keytmplen, &pvaltmp, &valtmplen, &rescode);
1271
+ result = pComObj->KeyQueueCommandSend(reinterpret_cast<const unsigned char*>(_strprefix.c_str()), _strprefix.length() + 1, _is_fifo, true, (_strpass.empty() ? NULL : _strpass.c_str()), &pkeytmp, &keytmplen, &pvaltmp, &valtmplen, &rescode);
1211
1272
  if(result && (pkeytmp && 0 < keytmplen)){
1212
- is_res_key_set = true;
1213
- strreskey = std::string(reinterpret_cast<const char*>(pkeytmp), keytmplen);
1273
+ _is_res_key_set = true;
1274
+ _strreskey = std::string(reinterpret_cast<const char*>(pkeytmp), ('\0' == pkeytmp[keytmplen - 1] ? keytmplen - 1 : keytmplen));
1214
1275
  if(pvaltmp && 0 < valtmplen){
1215
- is_res_val_set = true;
1216
- strresval = std::string(reinterpret_cast<const char*>(pvaltmp), valtmplen);
1276
+ _is_res_val_set = true;
1277
+ _strresval = std::string(reinterpret_cast<const char*>(pvaltmp), ('\0' == pvaltmp[valtmplen - 1] ? valtmplen - 1 : valtmplen));
1217
1278
  }
1218
1279
  }
1219
1280
  }else{
1220
1281
  // queue
1221
1282
  const unsigned char* pvaltmp = NULL;
1222
1283
  size_t valtmplen = 0L;
1223
- result = pComObj->QueueCommandSend(reinterpret_cast<const unsigned char*>(strprefix.c_str()), strprefix.length() + 1, is_fifo, true, (is_pass_set ? strpass.c_str() : NULL), &pvaltmp, &valtmplen, &rescode);
1284
+ result = pComObj->QueueCommandSend(reinterpret_cast<const unsigned char*>(_strprefix.c_str()), _strprefix.length() + 1, _is_fifo, true, (_strpass.empty() ? NULL : _strpass.c_str()), &pvaltmp, &valtmplen, &rescode);
1224
1285
 
1225
1286
  if(result && (pvaltmp && 0 < valtmplen)){
1226
- is_res_val_set = true;
1227
- strresval = std::string(reinterpret_cast<const char*>(pvaltmp), valtmplen);
1287
+ _is_res_val_set = true;
1288
+ _strresval = std::string(reinterpret_cast<const char*>(pvaltmp), ('\0' == pvaltmp[valtmplen - 1] ? valtmplen - 1 : valtmplen));
1228
1289
  }
1229
1290
  }
1230
1291
  DKC_DELETE(pComObj);
1231
1292
  }
1232
1293
 
1233
- void HandleOKCallback()
1294
+ // handler for success
1295
+ void OnOK() override
1234
1296
  {
1235
- Nan::HandleScope scope;
1236
-
1237
- if(!callback){
1238
- Nan::ThrowSyntaxError("Internal error in async worker");
1239
- return;
1240
- }
1241
- if(is_key_queue){
1242
- const int argc = 3;
1243
- if(is_res_key_set){
1244
- if(is_res_val_set){
1245
- v8::Local<v8::Value> argv[argc] = { Nan::Null(), Nan::New<v8::String>(strreskey.c_str()).ToLocalChecked(), Nan::New<v8::String>(strresval.c_str()).ToLocalChecked() };
1246
- callback->Call(argc, argv);
1297
+ Napi::Env env = Env();
1298
+ Napi::HandleScope scope(env);
1299
+
1300
+ if(!_callbackRef.IsEmpty()){
1301
+ if(_is_key_queue){
1302
+ if(_is_res_key_set){
1303
+ if(_is_res_val_set){
1304
+ Napi::String res_skey = Napi::String::New(env, _strreskey.c_str(), _strreskey.length());
1305
+ Napi::String res_sval = Napi::String::New(env, _strresval.c_str(), _strresval.length());
1306
+ _callbackRef.Value().Call({ env.Null(), res_skey, res_sval });
1307
+ }else{
1308
+
1309
+ Napi::String res_skey = Napi::String::New(env, _strreskey.c_str(), _strreskey.length());
1310
+ _callbackRef.Value().Call({ env.Null(), res_skey });
1311
+ }
1247
1312
  }else{
1248
- v8::Local<v8::Value> argv[argc] = { Nan::Null(), Nan::New<v8::String>(strreskey.c_str()).ToLocalChecked(), Nan::Null() };
1249
- callback->Call(argc, argv);
1313
+ _callbackRef.Value().Call({ env.Null(), env.Null(), env.Null() });
1250
1314
  }
1251
1315
  }else{
1252
- v8::Local<v8::Value> argv[argc] = { Nan::Null(), Nan::Null(), Nan::Null() };
1253
- callback->Call(argc, argv);
1316
+ if(_is_res_val_set){
1317
+ Napi::String res_sval = Napi::String::New(env, _strresval.c_str(), _strresval.length());
1318
+ _callbackRef.Value().Call({ env.Null(), res_sval });
1319
+ }else{
1320
+ _callbackRef.Value().Call({ env.Null(), env.Null() });
1321
+ }
1254
1322
  }
1255
1323
  }else{
1256
- const int argc = 2;
1257
- if(is_res_val_set){
1258
- v8::Local<v8::Value> argv[argc] = { Nan::Null(), Nan::New<v8::String>(strresval.c_str()).ToLocalChecked() };
1259
- callback->Call(argc, argv);
1260
- }else{
1261
- v8::Local<v8::Value> argv[argc] = { Nan::Null(), Nan::Null() };
1262
- callback->Call(argc, argv);
1263
- }
1324
+ Napi::TypeError::New(env, "Internal error in async worker").ThrowAsJavaScriptException();
1264
1325
  }
1265
1326
  }
1266
1327
 
1267
- void HandleErrorCallback()
1268
- {
1269
- Nan::HandleScope scope;
1270
- const int argc = 1;
1271
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
1328
+ // handler for failure (by calling SetError)
1329
+ void OnError(const Napi::Error& err) override
1330
+ {
1331
+ Napi::Env env = Env();
1332
+ Napi::HandleScope scope(env);
1272
1333
 
1273
- if(callback){
1274
- callback->Call(argc, argv);
1334
+ // The first argument is the error message.
1335
+ if(!_callbackRef.IsEmpty()){
1336
+ _callbackRef.Value().Call({ Napi::String::New(env, err.Value().ToString().Utf8Value()) });
1275
1337
  }else{
1276
- Nan::ThrowSyntaxError("Internal error in async worker");
1277
- return;
1338
+ // Throw error
1339
+ err.ThrowAsJavaScriptException();
1278
1340
  }
1279
- }
1341
+ }
1280
1342
 
1281
1343
  private:
1282
- K2hdkcSlave* pslaveobj;
1283
-
1284
- bool is_set_conf;
1285
- std::string conf;
1286
- int16_t ctlport;
1287
- std::string cuk;
1288
- bool auto_rejoin;
1289
- bool no_giveup_rejoin;
1290
-
1291
- bool is_prefix_set;
1292
- std::string strprefix;
1293
- bool is_fifo;
1294
- bool is_key_queue;
1295
- bool is_pass_set;
1296
- std::string strpass;
1297
-
1298
- bool is_res_key_set;
1299
- std::string strreskey;
1300
- bool is_res_val_set;
1301
- std::string strresval;
1344
+ Napi::FunctionReference _callbackRef;
1345
+ K2hdkcSlave& _slaveobj;
1346
+ std::string _conf;
1347
+ int16_t _ctlport;
1348
+ std::string _cuk;
1349
+ bool _auto_rejoin;
1350
+ bool _no_giveup_rejoin;
1351
+
1352
+ std::string _strprefix;
1353
+ bool _is_fifo;
1354
+ bool _is_key_queue;
1355
+ std::string _strpass;
1356
+
1357
+ bool _is_res_key_set;
1358
+ std::string _strreskey;
1359
+ bool _is_res_val_set;
1360
+ std::string _strresval;
1302
1361
  };
1303
1362
 
1304
1363
  //---------------------------------------------------------
1305
1364
  // QueueRemoveWorker class
1306
1365
  //
1307
- // Constructor: constructor(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pprefix, int remove_count, bool is_fifo_type, bool is_key_queue_type, const char* ppass)
1308
- // Callback function: function(string error[[, string key], string value])
1366
+ // Constructor: constructor(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& prefix, int remove_count, bool is_fifo_type, bool is_key_queue_type, const std::string& pass)
1367
+ // Callback function: function(string error)
1309
1368
  //
1310
1369
  //---------------------------------------------------------
1311
- class QueueRemoveWorker : public Nan::AsyncWorker
1370
+ class QueueRemoveWorker : public Napi::AsyncWorker
1312
1371
  {
1313
1372
  public:
1314
- QueueRemoveWorker(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, const char* inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pprefix, int remove_count, bool is_fifo_type, bool is_key_queue_type, const char* ppass) :
1315
- Nan::AsyncWorker(callback), pslaveobj(pobj),
1316
- is_set_conf(NULL != configuration), conf(configuration ? configuration : ""), ctlport(control_port), cuk(inputcuk ? inputcuk : ""), auto_rejoin(is_auto_rejoin), no_giveup_rejoin(is_nogiveup_rejoin),
1317
- is_prefix_set(NULL != pprefix), strprefix(pprefix ? pprefix : ""), count(remove_count), is_fifo(is_fifo_type), is_key_queue(is_key_queue_type), is_pass_set(NULL != ppass), strpass(ppass ? ppass : "")
1318
- {}
1373
+ QueueRemoveWorker(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& prefix, int remove_count, bool is_fifo_type, bool is_key_queue_type, const std::string& pass) :
1374
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)),
1375
+ _slaveobj(slaveobj), _conf(configuration), _ctlport(control_port), _cuk(inputcuk), _auto_rejoin(is_auto_rejoin), _no_giveup_rejoin(is_nogiveup_rejoin), _strprefix(prefix), _rmcount(remove_count), _is_fifo(is_fifo_type), _is_key_queue(is_key_queue_type), _strpass(pass)
1376
+ {
1377
+ _callbackRef.Ref();
1378
+ }
1319
1379
 
1320
- ~QueueRemoveWorker() {}
1380
+ ~QueueRemoveWorker() override
1381
+ {
1382
+ if(_callbackRef){
1383
+ _callbackRef.Unref();
1384
+ _callbackRef.Reset();
1385
+ }
1386
+ }
1321
1387
 
1322
- void Execute()
1388
+ // Run on worker thread
1389
+ void Execute() override
1323
1390
  {
1324
- if(!pslaveobj && !is_set_conf){
1391
+ if(!_slaveobj.GetChmCntrlObject() && _conf.empty()){
1325
1392
  // onetime connection mode needs configuration
1326
- this->SetErrorMessage("No configuration is associated to async worker");
1393
+ SetError("No configuration is associated to async worker");
1327
1394
  return;
1328
1395
  }
1329
- if(!is_prefix_set){
1330
- this->SetErrorMessage("Specified prefix is empty(null)");
1396
+ if(_strprefix.empty()){
1397
+ SetError("Specified prefix is empty(null)");
1331
1398
  return;
1332
1399
  }
1333
1400
 
1334
1401
  // work
1335
1402
  K2hdkcComQDel* pComObj;
1336
- if(!pslaveobj){
1337
- pComObj = GetOtSlaveK2hdkcComQDel(conf.c_str(), ctlport, (cuk.empty() ? NULL : cuk.c_str()), auto_rejoin, no_giveup_rejoin);
1403
+ if(!_slaveobj.GetChmCntrlObject()){
1404
+ pComObj = GetOtSlaveK2hdkcComQDel(_conf.c_str(), _ctlport, (_cuk.empty() ? NULL : _cuk.c_str()), _auto_rejoin, _no_giveup_rejoin);
1338
1405
  }else{
1339
- pComObj = GetPmSlaveK2hdkcComQDel(pslaveobj);
1406
+ pComObj = GetPmSlaveK2hdkcComQDel(&_slaveobj);
1340
1407
  }
1341
1408
  if(!pComObj){
1342
- this->SetErrorMessage("Internal error: Could not create command object.");
1409
+ SetError("Internal error: Could not create command object.");
1343
1410
  return;
1344
1411
  }
1345
1412
 
1346
1413
  dkcres_type_t rescode = DKC_NORESTYPE;
1347
1414
  bool result = false;
1348
- if(is_key_queue){
1415
+ if(_is_key_queue){
1349
1416
  // key queue
1350
- result = pComObj->KeyQueueCommandSend(reinterpret_cast<const unsigned char*>(strprefix.c_str()), strprefix.length() + 1, count, is_fifo, true, (is_pass_set ? strpass.c_str() : NULL), &rescode);
1417
+ result = pComObj->KeyQueueCommandSend(reinterpret_cast<const unsigned char*>(_strprefix.c_str()), _strprefix.length() + 1, _rmcount, _is_fifo, true, (_strpass.empty() ? NULL : _strpass.c_str()), &rescode);
1351
1418
  }else{
1352
1419
  // queue
1353
- result = pComObj->QueueCommandSend(reinterpret_cast<const unsigned char*>(strprefix.c_str()), strprefix.length() + 1, count, is_fifo, true, (is_pass_set ? strpass.c_str() : NULL), &rescode);
1420
+ result = pComObj->QueueCommandSend(reinterpret_cast<const unsigned char*>(_strprefix.c_str()), _strprefix.length() + 1, _rmcount, _is_fifo, true, (_strpass.empty() ? NULL : _strpass.c_str()), &rescode);
1354
1421
  }
1355
1422
  if(!result){
1356
- this->SetErrorMessage("Failed to remove queue.");
1423
+ SetError("Failed to remove queue.");
1357
1424
  }
1358
1425
  DKC_DELETE(pComObj);
1359
1426
  }
1360
1427
 
1361
- void HandleOKCallback()
1428
+ // handler for success
1429
+ void OnOK() override
1362
1430
  {
1363
- Nan::HandleScope scope;
1364
- const int argc = 1;
1365
- v8::Local<v8::Value> argv[argc] = { Nan::Null() };
1431
+ Napi::Env env = Env();
1432
+ Napi::HandleScope scope(env);
1366
1433
 
1367
- if(callback){
1368
- callback->Call(argc, argv);
1434
+ if(!_callbackRef.IsEmpty()){
1435
+ _callbackRef.Value().Call({ env.Null() });
1369
1436
  }else{
1370
- Nan::ThrowSyntaxError("Internal error in async worker");
1371
- return;
1437
+ Napi::TypeError::New(env, "Internal error in async worker");
1372
1438
  }
1373
1439
  }
1374
1440
 
1375
- void HandleErrorCallback()
1376
- {
1377
- Nan::HandleScope scope;
1378
- const int argc = 1;
1379
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
1441
+ // handler for failure (by calling SetError)
1442
+ void OnError(const Napi::Error& err) override
1443
+ {
1444
+ Napi::Env env = Env();
1445
+ Napi::HandleScope scope(env);
1380
1446
 
1381
- if(callback){
1382
- callback->Call(argc, argv);
1447
+ // The first argument is the error message.
1448
+ if(!_callbackRef.IsEmpty()){
1449
+ _callbackRef.Value().Call({ Napi::String::New(env, err.Value().ToString().Utf8Value()) });
1383
1450
  }else{
1384
- Nan::ThrowSyntaxError("Internal error in async worker");
1385
- return;
1451
+ // Throw error
1452
+ err.ThrowAsJavaScriptException();
1386
1453
  }
1387
- }
1454
+ }
1388
1455
 
1389
1456
  private:
1390
- K2hdkcSlave* pslaveobj;
1391
-
1392
- bool is_set_conf;
1393
- std::string conf;
1394
- int16_t ctlport;
1395
- std::string cuk;
1396
- bool auto_rejoin;
1397
- bool no_giveup_rejoin;
1398
-
1399
- bool is_prefix_set;
1400
- std::string strprefix;
1401
- int count;
1402
- bool is_fifo;
1403
- bool is_key_queue;
1404
- bool is_pass_set;
1405
- std::string strpass;
1457
+ Napi::FunctionReference _callbackRef;
1458
+ K2hdkcSlave& _slaveobj;
1459
+ std::string _conf;
1460
+ int16_t _ctlport;
1461
+ std::string _cuk;
1462
+ bool _auto_rejoin;
1463
+ bool _no_giveup_rejoin;
1464
+
1465
+ std::string _strprefix;
1466
+ int _rmcount;
1467
+ bool _is_fifo;
1468
+ bool _is_key_queue;
1469
+ std::string _strpass;
1406
1470
  };
1407
1471
 
1408
1472
  //---------------------------------------------------------
1409
1473
  // CasInitWorker class
1410
1474
  //
1411
- // Constructor: constructor(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pkey, uint32_t val, const char* ppass, const time_t* pexpire)
1475
+ // Constructor: constructor(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& key, uint32_t val, const std::string& pass, const time_t input_expire)
1412
1476
  // Callback function: function(string error)
1413
1477
  //
1414
1478
  //---------------------------------------------------------
1415
- class CasInitWorker : public Nan::AsyncWorker
1479
+ class CasInitWorker : public Napi::AsyncWorker
1416
1480
  {
1417
1481
  public:
1418
- CasInitWorker(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, const char* inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pkey, uint32_t val, const char* ppass, const time_t* pexpire) :
1419
- Nan::AsyncWorker(callback), pslaveobj(pobj),
1420
- is_set_conf(NULL != configuration), conf(configuration ? configuration : ""), ctlport(control_port), cuk(inputcuk ? inputcuk : ""), auto_rejoin(is_auto_rejoin), no_giveup_rejoin(is_nogiveup_rejoin),
1421
- is_key_set(NULL != pkey), strkey(pkey ? pkey : ""), value(val), is_pass_set(NULL != ppass), strpass(ppass ? ppass : ""), expire(pexpire ? *pexpire : 0)
1422
- {}
1423
- ~CasInitWorker() {}
1482
+ CasInitWorker(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& key, uint32_t val, const std::string& pass, const time_t input_expire) :
1483
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)),
1484
+ _slaveobj(slaveobj), _conf(configuration), _ctlport(control_port), _cuk(inputcuk), _auto_rejoin(is_auto_rejoin), _no_giveup_rejoin(is_nogiveup_rejoin), _strkey(key), _value(val), _strpass(pass), _expire(input_expire)
1485
+ {
1486
+ _callbackRef.Ref();
1487
+ }
1424
1488
 
1425
- void Execute()
1489
+ ~CasInitWorker() override
1426
1490
  {
1427
- if(!pslaveobj && !is_set_conf){
1491
+ if(_callbackRef){
1492
+ _callbackRef.Unref();
1493
+ _callbackRef.Reset();
1494
+ }
1495
+ }
1496
+
1497
+ // Run on worker thread
1498
+ void Execute() override
1499
+ {
1500
+ if(!_slaveobj.GetChmCntrlObject() && _conf.empty()){
1428
1501
  // onetime connection mode needs configuration
1429
- this->SetErrorMessage("No configuration is associated to async worker");
1502
+ SetError("No configuration is associated to async worker");
1430
1503
  return;
1431
1504
  }
1432
- if(!is_key_set){
1433
- this->SetErrorMessage("Specified key is empty(null)");
1505
+ if(_strkey.empty()){
1506
+ SetError("Specified key is empty(null)");
1434
1507
  return;
1435
1508
  }
1436
1509
 
1437
1510
  // work
1438
1511
  K2hdkcComCasInit* pComObj;
1439
- if(!pslaveobj){
1440
- pComObj = GetOtSlaveK2hdkcComCasInit(conf.c_str(), ctlport, (cuk.empty() ? NULL : cuk.c_str()), auto_rejoin, no_giveup_rejoin);
1512
+ if(!_slaveobj.GetChmCntrlObject()){
1513
+ pComObj = GetOtSlaveK2hdkcComCasInit(_conf.c_str(), _ctlport, (_cuk.empty() ? NULL : _cuk.c_str()), _auto_rejoin, _no_giveup_rejoin);
1441
1514
  }else{
1442
- pComObj = GetPmSlaveK2hdkcComCasInit(pslaveobj);
1515
+ pComObj = GetPmSlaveK2hdkcComCasInit(&_slaveobj);
1443
1516
  }
1444
1517
  if(!pComObj){
1445
- this->SetErrorMessage("Internal error: Could not create command object.");
1518
+ SetError("Internal error: Could not create command object.");
1446
1519
  return;
1447
1520
  }
1448
1521
 
1449
1522
  dkcres_type_t rescode = DKC_NORESTYPE;
1450
- if(!pComObj->CommandSend(reinterpret_cast<const unsigned char*>(strkey.c_str()), strkey.length() + 1, reinterpret_cast<const unsigned char*>(&value), sizeof(uint32_t), (is_pass_set ? strpass.c_str() : NULL), (expire > 0 ? &expire : NULL), &rescode)){
1451
- this->SetErrorMessage("Failed to initialize CAS key and value.");
1523
+ if(!pComObj->CommandSend(reinterpret_cast<const unsigned char*>(_strkey.c_str()), _strkey.length() + 1, reinterpret_cast<const unsigned char*>(&_value), sizeof(uint32_t), (_strpass.empty() ? NULL : _strpass.c_str()), (_expire > 0 ? &_expire : NULL), &rescode)){
1524
+ SetError("Failed to initialize CAS key and value.");
1452
1525
  }
1453
1526
  DKC_DELETE(pComObj);
1454
1527
  }
1455
1528
 
1456
- void HandleOKCallback()
1529
+ // handler for success
1530
+ void OnOK() override
1457
1531
  {
1458
- Nan::HandleScope scope;
1459
- const int argc = 1;
1460
- v8::Local<v8::Value> argv[argc] = { Nan::Null() };
1532
+ Napi::Env env = Env();
1533
+ Napi::HandleScope scope(env);
1461
1534
 
1462
- if(callback){
1463
- callback->Call(argc, argv);
1535
+ if(!_callbackRef.IsEmpty()){
1536
+ _callbackRef.Value().Call({ env.Null() });
1464
1537
  }else{
1465
- Nan::ThrowSyntaxError("Internal error in async worker");
1466
- return;
1538
+ Napi::TypeError::New(env, "Internal error in async worker");
1467
1539
  }
1468
1540
  }
1469
1541
 
1470
- void HandleErrorCallback()
1471
- {
1472
- Nan::HandleScope scope;
1473
- const int argc = 1;
1474
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
1542
+ // handler for failure (by calling SetError)
1543
+ void OnError(const Napi::Error& err) override
1544
+ {
1545
+ Napi::Env env = Env();
1546
+ Napi::HandleScope scope(env);
1475
1547
 
1476
- if(callback){
1477
- callback->Call(argc, argv);
1548
+ // The first argument is the error message.
1549
+ if(!_callbackRef.IsEmpty()){
1550
+ _callbackRef.Value().Call({ Napi::String::New(env, err.Value().ToString().Utf8Value()) });
1478
1551
  }else{
1479
- Nan::ThrowSyntaxError("Internal error in async worker");
1480
- return;
1552
+ // Throw error
1553
+ err.ThrowAsJavaScriptException();
1481
1554
  }
1482
- }
1555
+ }
1483
1556
 
1484
1557
  private:
1485
- K2hdkcSlave* pslaveobj;
1486
-
1487
- bool is_set_conf;
1488
- std::string conf;
1489
- int16_t ctlport;
1490
- std::string cuk;
1491
- bool auto_rejoin;
1492
- bool no_giveup_rejoin;
1493
-
1494
- bool is_key_set;
1495
- std::string strkey;
1496
- uint32_t value;
1497
- bool is_pass_set;
1498
- std::string strpass;
1499
- time_t expire;
1558
+ Napi::FunctionReference _callbackRef;
1559
+ K2hdkcSlave& _slaveobj;
1560
+ std::string _conf;
1561
+ int16_t _ctlport;
1562
+ std::string _cuk;
1563
+ bool _auto_rejoin;
1564
+ bool _no_giveup_rejoin;
1565
+
1566
+ std::string _strkey;
1567
+ uint32_t _value;
1568
+ std::string _strpass;
1569
+ time_t _expire;
1500
1570
  };
1501
1571
 
1502
1572
  //---------------------------------------------------------
1503
1573
  // CasGetWorker class
1504
1574
  //
1505
- // Constructor: constructor(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pkey, const char* ppass)
1575
+ // Constructor: constructor(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& key, const std::string& pass)
1506
1576
  // Callback function: function(string error[, int value])
1507
1577
  //
1508
1578
  //---------------------------------------------------------
1509
- class CasGetWorker : public Nan::AsyncWorker
1579
+ class CasGetWorker : public Napi::AsyncWorker
1510
1580
  {
1511
1581
  public:
1512
- CasGetWorker(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, const char* inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pkey, const char* ppass) :
1513
- Nan::AsyncWorker(callback), pslaveobj(pobj),
1514
- is_set_conf(NULL != configuration), conf(configuration ? configuration : ""), ctlport(control_port), cuk(inputcuk ? inputcuk : ""), auto_rejoin(is_auto_rejoin), no_giveup_rejoin(is_nogiveup_rejoin),
1515
- is_key_set(NULL != pkey), strkey(pkey ? pkey : ""), is_pass_set(NULL != ppass), strpass(ppass ? ppass : ""), resvalue(0)
1516
- {}
1517
- ~CasGetWorker() {}
1582
+ CasGetWorker(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& key, const std::string& pass) :
1583
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)),
1584
+ _slaveobj(slaveobj), _conf(configuration), _ctlport(control_port), _cuk(inputcuk), _auto_rejoin(is_auto_rejoin), _no_giveup_rejoin(is_nogiveup_rejoin), _strkey(key), _strpass(pass), _resvalue(0)
1585
+ {
1586
+ _callbackRef.Ref();
1587
+ }
1588
+
1589
+ ~CasGetWorker() override
1590
+ {
1591
+ if(_callbackRef){
1592
+ _callbackRef.Unref();
1593
+ _callbackRef.Reset();
1594
+ }
1595
+ }
1518
1596
 
1519
- void Execute()
1597
+ // Run on worker thread
1598
+ void Execute() override
1520
1599
  {
1521
- if(!pslaveobj && !is_set_conf){
1600
+ if(!_slaveobj.GetChmCntrlObject() && _conf.empty()){
1522
1601
  // onetime connection mode needs configuration
1523
- this->SetErrorMessage("No configuration is associated to async worker");
1602
+ SetError("No configuration is associated to async worker");
1524
1603
  return;
1525
1604
  }
1526
- if(!is_key_set){
1527
- this->SetErrorMessage("Specified key is empty(null)");
1605
+ if(_strkey.empty()){
1606
+ SetError("Specified key is empty(null)");
1528
1607
  return;
1529
1608
  }
1530
1609
 
1531
1610
  // work
1532
1611
  K2hdkcComCasGet* pComObj;
1533
- if(!pslaveobj){
1534
- pComObj = GetOtSlaveK2hdkcComCasGet(conf.c_str(), ctlport, (cuk.empty() ? NULL : cuk.c_str()), auto_rejoin, no_giveup_rejoin);
1612
+ if(!_slaveobj.GetChmCntrlObject()){
1613
+ pComObj = GetOtSlaveK2hdkcComCasGet(_conf.c_str(), _ctlport, (_cuk.empty() ? NULL : _cuk.c_str()), _auto_rejoin, _no_giveup_rejoin);
1535
1614
  }else{
1536
- pComObj = GetPmSlaveK2hdkcComCasGet(pslaveobj);
1615
+ pComObj = GetPmSlaveK2hdkcComCasGet(&_slaveobj);
1537
1616
  }
1538
1617
  if(!pComObj){
1539
- this->SetErrorMessage("Internal error: Could not create command object.");
1618
+ SetError("Internal error: Could not create command object.");
1540
1619
  return;
1541
1620
  }
1542
1621
 
1543
1622
  dkcres_type_t rescode = DKC_NORESTYPE;
1544
1623
  const unsigned char* pvaltmp = NULL;
1545
1624
  size_t valtmplen = 0L;
1546
- if(pComObj->CommandSend(reinterpret_cast<const unsigned char*>(strkey.c_str()), strkey.length() + 1, true, (is_pass_set ? strpass.c_str() : NULL), &pvaltmp, &valtmplen, &rescode) && (valtmplen == sizeof(uint32_t))){
1547
- memcpy(reinterpret_cast<unsigned char*>(&resvalue), pvaltmp, valtmplen);
1625
+ if(pComObj->CommandSend(reinterpret_cast<const unsigned char*>(_strkey.c_str()), _strkey.length() + 1, true, (_strpass.empty() ? NULL : _strpass.c_str()), &pvaltmp, &valtmplen, &rescode) && (valtmplen == sizeof(uint32_t))){
1626
+ memcpy(reinterpret_cast<unsigned char*>(&_resvalue), pvaltmp, valtmplen);
1548
1627
  }else{
1549
- this->SetErrorMessage("Failed to get CAS value.");
1628
+ SetError("Failed to get CAS value.");
1550
1629
  }
1551
1630
  DKC_DELETE(pComObj);
1552
1631
  }
1553
1632
 
1554
- void HandleOKCallback()
1633
+ // handler for success
1634
+ void OnOK() override
1555
1635
  {
1556
- Nan::HandleScope scope;
1557
- const int argc = 2;
1558
- v8::Local<v8::Value> argv[argc] = { Nan::Null(), Nan::New(resvalue) };
1636
+ Napi::Env env = Env();
1637
+ Napi::HandleScope scope(env);
1559
1638
 
1560
- if(callback){
1561
- callback->Call(argc, argv);
1639
+ if(!_callbackRef.IsEmpty()){
1640
+ Napi::Number res_val = Napi::Number::New(env, _resvalue);
1641
+ _callbackRef.Value().Call({ env.Null(), res_val });
1562
1642
  }else{
1563
- Nan::ThrowSyntaxError("Internal error in async worker");
1564
- return;
1643
+ Napi::TypeError::New(env, "Internal error in async worker");
1565
1644
  }
1566
1645
  }
1567
1646
 
1568
- void HandleErrorCallback()
1569
- {
1570
- Nan::HandleScope scope;
1571
- const int argc = 1;
1572
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
1647
+ // handler for failure (by calling SetError)
1648
+ void OnError(const Napi::Error& err) override
1649
+ {
1650
+ Napi::Env env = Env();
1651
+ Napi::HandleScope scope(env);
1573
1652
 
1574
- if(callback){
1575
- callback->Call(argc, argv);
1653
+ // The first argument is the error message.
1654
+ if(!_callbackRef.IsEmpty()){
1655
+ _callbackRef.Value().Call({ Napi::String::New(env, err.Value().ToString().Utf8Value()) });
1576
1656
  }else{
1577
- Nan::ThrowSyntaxError("Internal error in async worker");
1578
- return;
1657
+ // Throw error
1658
+ err.ThrowAsJavaScriptException();
1579
1659
  }
1580
- }
1660
+ }
1581
1661
 
1582
1662
  private:
1583
- K2hdkcSlave* pslaveobj;
1584
-
1585
- bool is_set_conf;
1586
- std::string conf;
1587
- int16_t ctlport;
1588
- std::string cuk;
1589
- bool auto_rejoin;
1590
- bool no_giveup_rejoin;
1591
-
1592
- bool is_key_set;
1593
- std::string strkey;
1594
- bool is_pass_set;
1595
- std::string strpass;
1596
-
1597
- uint32_t resvalue;
1663
+ Napi::FunctionReference _callbackRef;
1664
+ K2hdkcSlave& _slaveobj;
1665
+ std::string _conf;
1666
+ int16_t _ctlport;
1667
+ std::string _cuk;
1668
+ bool _auto_rejoin;
1669
+ bool _no_giveup_rejoin;
1670
+ std::string _strkey;
1671
+ std::string _strpass;
1672
+
1673
+ uint32_t _resvalue;
1598
1674
  };
1599
1675
 
1600
1676
  //---------------------------------------------------------
1601
1677
  // CasSetWorker class
1602
1678
  //
1603
- // Constructor: constructor(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pkey, uint32_t oldvalue, uint32_t newvalue, const char* ppass, const time_t* pexpire)
1679
+ // Constructor: constructor(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& key, uint32_t oldvalue, uint32_t newvalue, const std::string& pass, const time_t input_expire)
1604
1680
  // Callback function: function(string error)
1605
1681
  //
1606
1682
  //---------------------------------------------------------
1607
- class CasSetWorker : public Nan::AsyncWorker
1683
+ class CasSetWorker : public Napi::AsyncWorker
1608
1684
  {
1609
1685
  public:
1610
- CasSetWorker(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, const char* inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pkey, uint32_t oldvalue, uint32_t newvalue, const char* ppass, const time_t* pexpire) :
1611
- Nan::AsyncWorker(callback), pslaveobj(pobj),
1612
- is_set_conf(NULL != configuration), conf(configuration ? configuration : ""), ctlport(control_port), cuk(inputcuk ? inputcuk : ""), auto_rejoin(is_auto_rejoin), no_giveup_rejoin(is_nogiveup_rejoin),
1613
- is_key_set(NULL != pkey), strkey(pkey ? pkey : ""), oldval(oldvalue), newval(newvalue), is_pass_set(NULL != ppass), strpass(ppass ? ppass : ""), expire(pexpire ? *pexpire : 0)
1614
- {}
1615
- ~CasSetWorker() {}
1686
+ CasSetWorker(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& key, uint32_t oldvalue, uint32_t newvalue, const std::string& pass, const time_t input_expire) :
1687
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)),
1688
+ _slaveobj(slaveobj), _conf(configuration), _ctlport(control_port), _cuk(inputcuk), _auto_rejoin(is_auto_rejoin), _no_giveup_rejoin(is_nogiveup_rejoin), _strkey(key), _oldval(oldvalue), _newval(newvalue), _strpass(pass), _expire(input_expire)
1689
+ {
1690
+ _callbackRef.Ref();
1691
+ }
1616
1692
 
1617
- void Execute()
1693
+ ~CasSetWorker() override
1618
1694
  {
1619
- if(!pslaveobj && !is_set_conf){
1695
+ if(_callbackRef){
1696
+ _callbackRef.Unref();
1697
+ _callbackRef.Reset();
1698
+ }
1699
+ }
1700
+
1701
+ // Run on worker thread
1702
+ void Execute() override
1703
+ {
1704
+ if(!_slaveobj.GetChmCntrlObject() && _conf.empty()){
1620
1705
  // onetime connection mode needs configuration
1621
- this->SetErrorMessage("No configuration is associated to async worker");
1706
+ SetError("No configuration is associated to async worker");
1622
1707
  return;
1623
1708
  }
1624
- if(!is_key_set){
1625
- this->SetErrorMessage("Specified key is empty(null)");
1709
+ if(_strkey.empty()){
1710
+ SetError("Specified key is empty(null)");
1626
1711
  return;
1627
1712
  }
1628
1713
 
1629
1714
  // work
1630
1715
  K2hdkcComCasSet* pComObj;
1631
- if(!pslaveobj){
1632
- pComObj = GetOtSlaveK2hdkcComCasSet(conf.c_str(), ctlport, (cuk.empty() ? NULL : cuk.c_str()), auto_rejoin, no_giveup_rejoin);
1716
+ if(!_slaveobj.GetChmCntrlObject()){
1717
+ pComObj = GetOtSlaveK2hdkcComCasSet(_conf.c_str(), _ctlport, (_cuk.empty() ? NULL : _cuk.c_str()), _auto_rejoin, _no_giveup_rejoin);
1633
1718
  }else{
1634
- pComObj = GetPmSlaveK2hdkcComCasSet(pslaveobj);
1719
+ pComObj = GetPmSlaveK2hdkcComCasSet(&_slaveobj);
1635
1720
  }
1636
1721
  if(!pComObj){
1637
- this->SetErrorMessage("Internal error: Could not create command object.");
1722
+ SetError("Internal error: Could not create command object.");
1638
1723
  return;
1639
1724
  }
1640
1725
 
1641
1726
  dkcres_type_t rescode = DKC_NORESTYPE;
1642
- if(!pComObj->CommandSend(reinterpret_cast<const unsigned char*>(strkey.c_str()), strkey.length() + 1, reinterpret_cast<const unsigned char*>(&oldval), sizeof(uint32_t), reinterpret_cast<const unsigned char*>(&newval), sizeof(uint32_t), true, (is_pass_set ? strpass.c_str() : NULL), (expire > 0 ? &expire : NULL), &rescode)){
1643
- this->SetErrorMessage("Failed to set CAS value.");
1727
+ if(!pComObj->CommandSend(reinterpret_cast<const unsigned char*>(_strkey.c_str()), _strkey.length() + 1, reinterpret_cast<const unsigned char*>(&_oldval), sizeof(uint32_t), reinterpret_cast<const unsigned char*>(&_newval), sizeof(uint32_t), true, (_strpass.empty() ? NULL : _strpass.c_str()), (_expire > 0 ? &_expire : NULL), &rescode)){
1728
+ SetError("Failed to set CAS value.");
1644
1729
  }
1645
1730
  DKC_DELETE(pComObj);
1646
1731
  }
1647
1732
 
1648
- void HandleOKCallback()
1733
+ // handler for success
1734
+ void OnOK() override
1649
1735
  {
1650
- Nan::HandleScope scope;
1651
- const int argc = 1;
1652
- v8::Local<v8::Value> argv[argc] = { Nan::Null() };
1736
+ Napi::Env env = Env();
1737
+ Napi::HandleScope scope(env);
1653
1738
 
1654
- if(callback){
1655
- callback->Call(argc, argv);
1739
+ if(!_callbackRef.IsEmpty()){
1740
+ _callbackRef.Value().Call({ env.Null() });
1656
1741
  }else{
1657
- Nan::ThrowSyntaxError("Internal error in async worker");
1658
- return;
1742
+ Napi::TypeError::New(env, "Internal error in async worker");
1659
1743
  }
1660
1744
  }
1661
1745
 
1662
- void HandleErrorCallback()
1663
- {
1664
- Nan::HandleScope scope;
1665
- const int argc = 1;
1666
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
1746
+ // handler for failure (by calling SetError)
1747
+ void OnError(const Napi::Error& err) override
1748
+ {
1749
+ Napi::Env env = Env();
1750
+ Napi::HandleScope scope(env);
1667
1751
 
1668
- if(callback){
1669
- callback->Call(argc, argv);
1752
+ // The first argument is the error message.
1753
+ if(!_callbackRef.IsEmpty()){
1754
+ _callbackRef.Value().Call({ Napi::String::New(env, err.Value().ToString().Utf8Value()) });
1670
1755
  }else{
1671
- Nan::ThrowSyntaxError("Internal error in async worker");
1672
- return;
1756
+ // Throw error
1757
+ err.ThrowAsJavaScriptException();
1673
1758
  }
1674
- }
1759
+ }
1675
1760
 
1676
1761
  private:
1677
- K2hdkcSlave* pslaveobj;
1678
-
1679
- bool is_set_conf;
1680
- std::string conf;
1681
- int16_t ctlport;
1682
- std::string cuk;
1683
- bool auto_rejoin;
1684
- bool no_giveup_rejoin;
1685
-
1686
- bool is_key_set;
1687
- std::string strkey;
1688
- uint32_t oldval;
1689
- uint32_t newval;
1690
- bool is_pass_set;
1691
- std::string strpass;
1692
- time_t expire;
1762
+ Napi::FunctionReference _callbackRef;
1763
+ K2hdkcSlave& _slaveobj;
1764
+ std::string _conf;
1765
+ int16_t _ctlport;
1766
+ std::string _cuk;
1767
+ bool _auto_rejoin;
1768
+ bool _no_giveup_rejoin;
1769
+
1770
+ std::string _strkey;
1771
+ uint32_t _oldval;
1772
+ uint32_t _newval;
1773
+ std::string _strpass;
1774
+ time_t _expire;
1693
1775
  };
1694
1776
 
1695
1777
  //---------------------------------------------------------
1696
1778
  // CasIncDecWorker class
1697
1779
  //
1698
- // Constructor: constructor(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pkey, bool is_increment_type, const char* ppass, const time_t* pexpire)
1780
+ // Constructor: constructor(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& key, bool is_increment_type, const std::string& pass, const time_t input_expire)
1699
1781
  // Callback function: function(string error)
1700
1782
  //
1701
1783
  //---------------------------------------------------------
1702
- class CasIncDecWorker : public Nan::AsyncWorker
1784
+ class CasIncDecWorker : public Napi::AsyncWorker
1703
1785
  {
1704
1786
  public:
1705
- CasIncDecWorker(Nan::Callback* callback, K2hdkcSlave* pobj, const char* configuration, int control_port, const char* inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const char* pkey, bool is_increment_type, const char* ppass, const time_t* pexpire) :
1706
- Nan::AsyncWorker(callback), pslaveobj(pobj),
1707
- is_set_conf(NULL != configuration), conf(configuration ? configuration : ""), ctlport(control_port), cuk(inputcuk ? inputcuk : ""), auto_rejoin(is_auto_rejoin), no_giveup_rejoin(is_nogiveup_rejoin),
1708
- is_key_set(NULL != pkey), strkey(pkey ? pkey : ""), is_increment(is_increment_type), is_pass_set(NULL != ppass), strpass(ppass ? ppass : ""), expire(pexpire ? *pexpire : 0)
1709
- {}
1710
- ~CasIncDecWorker() {}
1787
+ CasIncDecWorker(const Napi::Function& callback, K2hdkcSlave& slaveobj, const std::string& configuration, int control_port, const std::string& inputcuk, bool is_auto_rejoin, bool is_nogiveup_rejoin, const std::string& key, bool is_increment_type, const std::string& pass, const time_t input_expire) :
1788
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)),
1789
+ _slaveobj(slaveobj), _conf(configuration), _ctlport(control_port), _cuk(inputcuk), _auto_rejoin(is_auto_rejoin), _no_giveup_rejoin(is_nogiveup_rejoin), _strkey(key), _is_increment(is_increment_type), _strpass(pass), _expire(input_expire)
1790
+ {
1791
+ _callbackRef.Ref();
1792
+ }
1711
1793
 
1712
- void Execute()
1794
+ ~CasIncDecWorker() override
1713
1795
  {
1714
- if(!pslaveobj && !is_set_conf){
1796
+ if(_callbackRef){
1797
+ _callbackRef.Unref();
1798
+ _callbackRef.Reset();
1799
+ }
1800
+ }
1801
+
1802
+ // Run on worker thread
1803
+ void Execute() override
1804
+ {
1805
+ if(!_slaveobj.GetChmCntrlObject() && _conf.empty()){
1715
1806
  // onetime connection mode needs configuration
1716
- this->SetErrorMessage("No configuration is associated to async worker");
1807
+ SetError("No configuration is associated to async worker");
1717
1808
  return;
1718
1809
  }
1719
- if(!is_key_set){
1720
- this->SetErrorMessage("Specified key is empty(null)");
1810
+ if(_strkey.empty()){
1811
+ SetError("Specified key is empty(null)");
1721
1812
  return;
1722
1813
  }
1723
1814
 
1724
1815
  // work
1725
1816
  K2hdkcComCasIncDec* pComObj;
1726
- if(!pslaveobj){
1727
- pComObj = GetOtSlaveK2hdkcComCasIncDec(conf.c_str(), ctlport, (cuk.empty() ? NULL : cuk.c_str()), auto_rejoin, no_giveup_rejoin);
1817
+ if(!_slaveobj.GetChmCntrlObject()){
1818
+ pComObj = GetOtSlaveK2hdkcComCasIncDec(_conf.c_str(), _ctlport, (_cuk.empty() ? NULL : _cuk.c_str()), _auto_rejoin, _no_giveup_rejoin);
1728
1819
  }else{
1729
- pComObj = GetPmSlaveK2hdkcComCasIncDec(pslaveobj);
1820
+ pComObj = GetPmSlaveK2hdkcComCasIncDec(&_slaveobj);
1730
1821
  }
1731
1822
  if(!pComObj){
1732
- this->SetErrorMessage("Internal error: Could not create command object.");
1823
+ SetError("Internal error: Could not create command object.");
1733
1824
  return;
1734
1825
  }
1735
1826
 
1736
1827
  dkcres_type_t rescode = DKC_NORESTYPE;
1737
- if(!pComObj->CommandSend(reinterpret_cast<const unsigned char*>(strkey.c_str()), strkey.length() + 1, is_increment, true, (is_pass_set ? strpass.c_str() : NULL), (expire > 0 ? &expire : NULL), &rescode)){
1738
- if(is_increment){
1739
- this->SetErrorMessage("Failed to increment CAS value.");
1828
+ if(!pComObj->CommandSend(reinterpret_cast<const unsigned char*>(_strkey.c_str()), _strkey.length() + 1, _is_increment, true, (_strpass.empty() ? NULL : _strpass.c_str()), (_expire > 0 ? &_expire : NULL), &rescode)){
1829
+ if(_is_increment){
1830
+ SetError("Failed to increment CAS value.");
1740
1831
  }else{
1741
- this->SetErrorMessage("Failed to decrement CAS value.");
1832
+ SetError("Failed to decrement CAS value.");
1742
1833
  }
1743
1834
  }
1744
1835
  DKC_DELETE(pComObj);
1745
1836
  }
1746
1837
 
1747
- void HandleOKCallback()
1838
+ // handler for success
1839
+ void OnOK() override
1748
1840
  {
1749
- Nan::HandleScope scope;
1750
- const int argc = 1;
1751
- v8::Local<v8::Value> argv[argc] = { Nan::Null() };
1841
+ Napi::Env env = Env();
1842
+ Napi::HandleScope scope(env);
1752
1843
 
1753
- if(callback){
1754
- callback->Call(argc, argv);
1844
+ if(!_callbackRef.IsEmpty()){
1845
+ _callbackRef.Value().Call({ env.Null() });
1755
1846
  }else{
1756
- Nan::ThrowSyntaxError("Internal error in async worker");
1757
- return;
1847
+ Napi::TypeError::New(env, "Internal error in async worker");
1758
1848
  }
1759
1849
  }
1760
1850
 
1761
- void HandleErrorCallback()
1762
- {
1763
- Nan::HandleScope scope;
1764
- const int argc = 1;
1765
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
1851
+ // handler for failure (by calling SetError)
1852
+ void OnError(const Napi::Error& err) override
1853
+ {
1854
+ Napi::Env env = Env();
1855
+ Napi::HandleScope scope(env);
1766
1856
 
1767
- if(callback){
1768
- callback->Call(argc, argv);
1857
+ // The first argument is the error message.
1858
+ if(!_callbackRef.IsEmpty()){
1859
+ _callbackRef.Value().Call({ Napi::String::New(env, err.Value().ToString().Utf8Value()) });
1769
1860
  }else{
1770
- Nan::ThrowSyntaxError("Internal error in async worker");
1771
- return;
1861
+ // Throw error
1862
+ err.ThrowAsJavaScriptException();
1772
1863
  }
1773
- }
1864
+ }
1774
1865
 
1775
1866
  private:
1776
- K2hdkcSlave* pslaveobj;
1777
-
1778
- bool is_set_conf;
1779
- std::string conf;
1780
- int16_t ctlport;
1781
- std::string cuk;
1782
- bool auto_rejoin;
1783
- bool no_giveup_rejoin;
1784
-
1785
- bool is_key_set;
1786
- std::string strkey;
1787
- bool is_increment;
1788
- bool is_pass_set;
1789
- std::string strpass;
1790
- time_t expire;
1867
+ Napi::FunctionReference _callbackRef;
1868
+ K2hdkcSlave& _slaveobj;
1869
+ std::string _conf;
1870
+ int16_t _ctlport;
1871
+ std::string _cuk;
1872
+ bool _auto_rejoin;
1873
+ bool _no_giveup_rejoin;
1874
+
1875
+ std::string _strkey;
1876
+ bool _is_increment;
1877
+ std::string _strpass;
1878
+ time_t _expire;
1791
1879
  };
1792
1880
 
1793
1881
  #endif