node.js binding fixes
This commit is contained in:
@@ -24,7 +24,7 @@ NAN_MODULE_INIT(InitAddon)
|
||||
|
||||
tpl = Nan::New<v8::FunctionTemplate>(NodeVitastorImage::Create);
|
||||
tpl->SetClassName(Nan::New("Image").ToLocalChecked());
|
||||
tpl->InstanceTemplate()->SetInternalFieldCount(2);
|
||||
tpl->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
|
||||
Nan::SetPrototypeMethod(tpl, "read", NodeVitastorImage::Read);
|
||||
Nan::SetPrototypeMethod(tpl, "write", NodeVitastorImage::Write);
|
||||
@@ -67,7 +67,7 @@ NAN_MODULE_INIT(InitAddon)
|
||||
|
||||
tpl = Nan::New<v8::FunctionTemplate>(NodeVitastorKVListing::Create);
|
||||
tpl->SetClassName(Nan::New("KVListing").ToLocalChecked());
|
||||
tpl->InstanceTemplate()->SetInternalFieldCount(2);
|
||||
tpl->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
|
||||
Nan::SetPrototypeMethod(tpl, "next", NodeVitastorKVListing::Next);
|
||||
Nan::SetPrototypeMethod(tpl, "close", NodeVitastorKVListing::Close);
|
||||
|
||||
@@ -10,10 +10,11 @@
|
||||
'<!(node -e "require(\'nan\')")'
|
||||
],
|
||||
'cflags': [
|
||||
'<!(pkg-config --cflags vitastor)'
|
||||
'<!(pkg-config --cflags vitastor) -g'
|
||||
],
|
||||
'libraries': [
|
||||
'<!(pkg-config --libs vitastor)'
|
||||
'<!(pkg-config --libs vitastor)',
|
||||
'-lvitastor_kv'
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
+175
-84
@@ -18,13 +18,15 @@
|
||||
class NodeVitastorRequest: public Nan::AsyncResource
|
||||
{
|
||||
public:
|
||||
NodeVitastorRequest(v8::Local<v8::Function> cb): Nan::AsyncResource("NodeVitastorRequest")
|
||||
NodeVitastorRequest(NodeVitastor *cli, v8::Local<v8::Function> cb): Nan::AsyncResource("NodeVitastorRequest")
|
||||
{
|
||||
this->cli = cli;
|
||||
callback.Reset(cb);
|
||||
}
|
||||
|
||||
iovec iov;
|
||||
std::vector<iovec> iov_list;
|
||||
NodeVitastor *cli = NULL;
|
||||
NodeVitastorImage *img = NULL;
|
||||
int op = 0;
|
||||
uint64_t offset = 0, len = 0, version = 0;
|
||||
@@ -44,6 +46,7 @@ NodeVitastor::NodeVitastor(): Nan::ObjectWrap()
|
||||
|
||||
NodeVitastor::~NodeVitastor()
|
||||
{
|
||||
TRACE("NodeVitastor: destructor");
|
||||
uv_poll_stop(&poll_watcher);
|
||||
vitastor_c_destroy(c);
|
||||
c = NULL;
|
||||
@@ -75,9 +78,10 @@ NAN_METHOD(NodeVitastor::Create)
|
||||
if (res >= 0)
|
||||
{
|
||||
cli->eventfd = res;
|
||||
res = uv_poll_init_socket(uv_default_loop(), &cli->poll_watcher, cli->eventfd);
|
||||
res = uv_poll_init(uv_default_loop(), &cli->poll_watcher, cli->eventfd);
|
||||
if (res >= 0)
|
||||
res = uv_poll_start(&cli->poll_watcher, UV_READABLE, on_io_readable);
|
||||
on_io_readable(&cli->poll_watcher, 0, UV_READABLE);
|
||||
}
|
||||
if (res < 0)
|
||||
{
|
||||
@@ -98,12 +102,28 @@ void NodeVitastor::on_io_readable(uv_poll_t* handle, int status, int revents)
|
||||
if (revents & UV_READABLE)
|
||||
{
|
||||
NodeVitastor* self = (NodeVitastor*)handle->data;
|
||||
std::unique_lock<std::mutex> lock(self->mu);
|
||||
vitastor_c_uring_handle_events(self->c);
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(self->mu);
|
||||
vitastor_c_uring_handle_events(self->c);
|
||||
}
|
||||
self->run_postponed();
|
||||
}
|
||||
}
|
||||
|
||||
static NodeVitastorRequest* getReadRequest(const Nan::FunctionCallbackInfo<v8::Value> & info, int argpos)
|
||||
void NodeVitastor::run_postponed()
|
||||
{
|
||||
std::vector<std::function<void()>> callbacks;
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mu);
|
||||
callbacks.swap(postponed);
|
||||
}
|
||||
for (auto & cb: callbacks)
|
||||
{
|
||||
cb();
|
||||
}
|
||||
}
|
||||
|
||||
NodeVitastorRequest* NodeVitastor::get_read_request(const Nan::FunctionCallbackInfo<v8::Value> & info, int argpos)
|
||||
{
|
||||
uint64_t offset = Nan::To<int64_t>(info[argpos+0]).FromJust();
|
||||
uint64_t len = Nan::To<int64_t>(info[argpos+1]).FromJust();
|
||||
@@ -114,7 +134,7 @@ static NodeVitastorRequest* getReadRequest(const Nan::FunctionCallbackInfo<v8::V
|
||||
return NULL;
|
||||
}
|
||||
v8::Local<v8::Function> callback = info[argpos+2].As<v8::Function>();
|
||||
auto req = new NodeVitastorRequest(callback);
|
||||
auto req = new NodeVitastorRequest(this, callback);
|
||||
|
||||
req->offset = offset;
|
||||
req->len = len;
|
||||
@@ -133,13 +153,17 @@ NAN_METHOD(NodeVitastor::Read)
|
||||
uint64_t pool = Nan::To<int64_t>(info[0]).FromJust();
|
||||
uint64_t inode = Nan::To<int64_t>(info[1]).FromJust();
|
||||
|
||||
auto req = getReadRequest(info, 2);
|
||||
auto req = self->get_read_request(info, 2);
|
||||
|
||||
std::unique_lock<std::mutex> lock(self->mu);
|
||||
vitastor_c_read(self->c, ((pool << (64-POOL_ID_BITS)) | inode), req->offset, req->len, &req->iov, 1, on_read_finish, req);
|
||||
self->Ref();
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(self->mu);
|
||||
vitastor_c_read(self->c, ((pool << (64-POOL_ID_BITS)) | inode), req->offset, req->len, &req->iov, 1, postpone_read_finish, req);
|
||||
}
|
||||
self->run_postponed();
|
||||
}
|
||||
|
||||
static NodeVitastorRequest* getWriteRequest(const Nan::FunctionCallbackInfo<v8::Value> & info, int argpos)
|
||||
NodeVitastorRequest* NodeVitastor::get_write_request(const Nan::FunctionCallbackInfo<v8::Value> & info, int argpos)
|
||||
{
|
||||
uint64_t offset = Nan::To<int64_t>(info[argpos+0]).FromJust();
|
||||
const auto & bufarg = info[argpos+1];
|
||||
@@ -155,7 +179,7 @@ static NodeVitastorRequest* getWriteRequest(const Nan::FunctionCallbackInfo<v8::
|
||||
}
|
||||
|
||||
v8::Local<v8::Function> callback = info[argpos+2].As<v8::Function>();
|
||||
auto req = new NodeVitastorRequest(callback);
|
||||
auto req = new NodeVitastorRequest(this, callback);
|
||||
|
||||
req->offset = offset;
|
||||
req->version = version;
|
||||
@@ -177,7 +201,7 @@ static NodeVitastorRequest* getWriteRequest(const Nan::FunctionCallbackInfo<v8::
|
||||
{
|
||||
char *buf = node::Buffer::Data(bufarg);
|
||||
uint64_t len = node::Buffer::Length(bufarg);
|
||||
req->iov = { .iov_base = buf, .iov_len = req->len };
|
||||
req->iov = { .iov_base = buf, .iov_len = len };
|
||||
req->len = len;
|
||||
}
|
||||
|
||||
@@ -194,13 +218,17 @@ NAN_METHOD(NodeVitastor::Write)
|
||||
uint64_t pool = Nan::To<int64_t>(info[0]).FromJust();
|
||||
uint64_t inode = Nan::To<int64_t>(info[1]).FromJust();
|
||||
|
||||
auto req = getWriteRequest(info, 2);
|
||||
auto req = self->get_write_request(info, 2);
|
||||
|
||||
std::unique_lock<std::mutex> lock(self->mu);
|
||||
vitastor_c_write(self->c, ((pool << (64-POOL_ID_BITS)) | inode), req->offset, req->len, req->version,
|
||||
req->iov_list.size() ? req->iov_list.data() : &req->iov,
|
||||
req->iov_list.size() ? req->iov_list.size() : 1,
|
||||
on_write_finish, req);
|
||||
self->Ref();
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(self->mu);
|
||||
vitastor_c_write(self->c, ((pool << (64-POOL_ID_BITS)) | inode), req->offset, req->len, req->version,
|
||||
req->iov_list.size() ? req->iov_list.data() : &req->iov,
|
||||
req->iov_list.size() ? req->iov_list.size() : 1,
|
||||
postpone_write_finish, req);
|
||||
}
|
||||
self->run_postponed();
|
||||
}
|
||||
|
||||
// sync(callback(err))
|
||||
@@ -211,10 +239,14 @@ NAN_METHOD(NodeVitastor::Sync)
|
||||
NodeVitastor* self = Nan::ObjectWrap::Unwrap<NodeVitastor>(info.This());
|
||||
|
||||
v8::Local<v8::Function> callback = info[0].As<v8::Function>();
|
||||
auto req = new NodeVitastorRequest(callback);
|
||||
auto req = new NodeVitastorRequest(self, callback);
|
||||
|
||||
std::unique_lock<std::mutex> lock(self->mu);
|
||||
vitastor_c_sync(self->c, on_write_finish, req);
|
||||
self->Ref();
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(self->mu);
|
||||
vitastor_c_sync(self->c, postpone_write_finish, req);
|
||||
}
|
||||
self->run_postponed();
|
||||
}
|
||||
|
||||
// read_bitmap(pool, inode, offset, len, with_parents, callback(err, bitmap_buffer))
|
||||
@@ -230,9 +262,14 @@ NAN_METHOD(NodeVitastor::ReadBitmap)
|
||||
uint64_t len = Nan::To<int64_t>(info[3]).FromJust();
|
||||
bool with_parents = Nan::To<bool>(info[4]).FromJust();
|
||||
v8::Local<v8::Function> callback = info[5].As<v8::Function>();
|
||||
auto req = new NodeVitastorRequest(self, callback);
|
||||
|
||||
auto req = new NodeVitastorRequest(callback);
|
||||
vitastor_c_read_bitmap(self->c, ((pool << (64-POOL_ID_BITS)) | inode), offset, len, with_parents, on_read_bitmap_finish, req);
|
||||
self->Ref();
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(self->mu);
|
||||
vitastor_c_read_bitmap(self->c, ((pool << (64-POOL_ID_BITS)) | inode), offset, len, with_parents, postpone_read_bitmap_finish, req);
|
||||
}
|
||||
self->run_postponed();
|
||||
}
|
||||
|
||||
static void on_error(NodeVitastorRequest *req, Nan::Callback & nanCallback, long retval)
|
||||
@@ -248,6 +285,7 @@ static void on_error(NodeVitastorRequest *req, Nan::Callback & nanCallback, long
|
||||
|
||||
void NodeVitastor::on_read_finish(void *opaque, long retval, uint64_t version)
|
||||
{
|
||||
TRACE("NodeVitastor::on_read_finish");
|
||||
Nan::HandleScope scope;
|
||||
NodeVitastorRequest *req = (NodeVitastorRequest *)opaque;
|
||||
Nan::Callback nanCallback(Nan::New(req->callback));
|
||||
@@ -269,20 +307,24 @@ void NodeVitastor::on_read_finish(void *opaque, long retval, uint64_t version)
|
||||
args[2] = v8::BigInt::NewFromUnsigned(v8::Isolate::GetCurrent(), version);
|
||||
nanCallback.Call(3, args, req);
|
||||
}
|
||||
req->cli->Unref();
|
||||
delete req;
|
||||
}
|
||||
|
||||
void NodeVitastor::on_write_finish(void *opaque, long retval)
|
||||
{
|
||||
TRACE("NodeVitastor::on_write_finish");
|
||||
Nan::HandleScope scope;
|
||||
NodeVitastorRequest *req = (NodeVitastorRequest *)opaque;
|
||||
Nan::Callback nanCallback(Nan::New(req->callback));
|
||||
on_error(req, nanCallback, retval);
|
||||
req->cli->Unref();
|
||||
delete req;
|
||||
}
|
||||
|
||||
void NodeVitastor::on_read_bitmap_finish(void *opaque, long retval, uint8_t *bitmap)
|
||||
{
|
||||
TRACE("NodeVitastor::on_read_bitmap_finish");
|
||||
Nan::HandleScope scope;
|
||||
NodeVitastorRequest *req = (NodeVitastorRequest *)opaque;
|
||||
Nan::Callback nanCallback(Nan::New(req->callback));
|
||||
@@ -297,9 +339,28 @@ void NodeVitastor::on_read_bitmap_finish(void *opaque, long retval, uint8_t *bit
|
||||
args[1] = Nan::NewBuffer((char*)bitmap, (retval+7)/8).ToLocalChecked();
|
||||
nanCallback.Call(2, args, req);
|
||||
}
|
||||
req->cli->Unref();
|
||||
delete req;
|
||||
}
|
||||
|
||||
void NodeVitastor::postpone_read_finish(void *opaque, long retval, uint64_t version)
|
||||
{
|
||||
NodeVitastorRequest *req = (NodeVitastorRequest *)opaque;
|
||||
req->cli->postponed.push_back([=]() { on_read_finish(opaque, retval, version); });
|
||||
}
|
||||
|
||||
void NodeVitastor::postpone_write_finish(void *opaque, long retval)
|
||||
{
|
||||
NodeVitastorRequest *req = (NodeVitastorRequest *)opaque;
|
||||
req->cli->postponed.push_back([=]() { on_write_finish(opaque, retval); });
|
||||
}
|
||||
|
||||
void NodeVitastor::postpone_read_bitmap_finish(void *opaque, long retval, uint8_t *bitmap)
|
||||
{
|
||||
NodeVitastorRequest *req = (NodeVitastorRequest *)opaque;
|
||||
req->cli->postponed.push_back([=]() { on_read_bitmap_finish(opaque, retval, bitmap); });
|
||||
}
|
||||
|
||||
//NAN_METHOD(NodeVitastor::Destroy)
|
||||
//{
|
||||
// TRACE("NodeVitastor::Destroy");
|
||||
@@ -318,6 +379,8 @@ NAN_METHOD(NodeVitastorImage::Create)
|
||||
NodeVitastor *cli = Nan::ObjectWrap::Unwrap<NodeVitastor>(parent);
|
||||
|
||||
NodeVitastorImage *img = new NodeVitastorImage();
|
||||
img->Wrap(info.This());
|
||||
|
||||
img->cli = cli;
|
||||
img->name = name;
|
||||
|
||||
@@ -326,7 +389,6 @@ NAN_METHOD(NodeVitastorImage::Create)
|
||||
std::unique_lock<std::mutex> lock(cli->mu);
|
||||
vitastor_c_watch_inode(cli->c, (char*)img->name.c_str(), on_watch_start, img);
|
||||
|
||||
img->Wrap(info.This());
|
||||
info.GetReturnValue().Set(info.This());
|
||||
}
|
||||
|
||||
@@ -347,7 +409,7 @@ NAN_METHOD(NodeVitastorImage::Read)
|
||||
|
||||
NodeVitastorImage* img = Nan::ObjectWrap::Unwrap<NodeVitastorImage>(info.This());
|
||||
|
||||
auto req = getReadRequest(info, 0);
|
||||
auto req = img->cli->get_read_request(info, 0);
|
||||
req->img = img;
|
||||
req->op = NODE_VITASTOR_READ;
|
||||
|
||||
@@ -361,7 +423,7 @@ NAN_METHOD(NodeVitastorImage::Write)
|
||||
|
||||
NodeVitastorImage* img = Nan::ObjectWrap::Unwrap<NodeVitastorImage>(info.This());
|
||||
|
||||
auto req = getWriteRequest(info, 0);
|
||||
auto req = img->cli->get_write_request(info, 0);
|
||||
req->img = img;
|
||||
req->op = NODE_VITASTOR_WRITE;
|
||||
|
||||
@@ -375,7 +437,7 @@ NAN_METHOD(NodeVitastorImage::Sync)
|
||||
NodeVitastorImage* img = Nan::ObjectWrap::Unwrap<NodeVitastorImage>(info.This());
|
||||
|
||||
v8::Local<v8::Function> callback = info[0].As<v8::Function>();
|
||||
auto req = new NodeVitastorRequest(callback);
|
||||
auto req = new NodeVitastorRequest(img->cli, callback);
|
||||
req->img = img;
|
||||
req->op = NODE_VITASTOR_SYNC;
|
||||
|
||||
@@ -394,7 +456,7 @@ NAN_METHOD(NodeVitastorImage::ReadBitmap)
|
||||
bool with_parents = Nan::To<bool>(info[2]).FromJust();
|
||||
v8::Local<v8::Function> callback = info[3].As<v8::Function>();
|
||||
|
||||
auto req = new NodeVitastorRequest(callback);
|
||||
auto req = new NodeVitastorRequest(img->cli, callback);
|
||||
req->img = img;
|
||||
req->op = NODE_VITASTOR_READ_BITMAP;
|
||||
req->offset = offset;
|
||||
@@ -406,12 +468,12 @@ NAN_METHOD(NodeVitastorImage::ReadBitmap)
|
||||
|
||||
NAN_METHOD(NodeVitastorImage::GetInfo)
|
||||
{
|
||||
TRACE("NodeVitastorImage::Sync");
|
||||
TRACE("NodeVitastorImage::GetInfo");
|
||||
|
||||
NodeVitastorImage* img = Nan::ObjectWrap::Unwrap<NodeVitastorImage>(info.This());
|
||||
|
||||
v8::Local<v8::Function> callback = info[0].As<v8::Function>();
|
||||
auto req = new NodeVitastorRequest(callback);
|
||||
auto req = new NodeVitastorRequest(img->cli, callback);
|
||||
req->img = img;
|
||||
req->op = NODE_VITASTOR_GET_INFO;
|
||||
|
||||
@@ -433,78 +495,52 @@ void NodeVitastorImage::exec_or_wait(NodeVitastorRequest *req)
|
||||
|
||||
void NodeVitastorImage::exec_request(NodeVitastorRequest *req)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(cli->mu);
|
||||
if (req->op == NODE_VITASTOR_READ)
|
||||
{
|
||||
cli->Ref();
|
||||
std::unique_lock<std::mutex> lock(cli->mu);
|
||||
uint64_t ino = vitastor_c_inode_get_num(watch);
|
||||
vitastor_c_read(cli->c, ino, req->offset, req->len, &req->iov, 1, NodeVitastor::on_read_finish, req);
|
||||
vitastor_c_read(cli->c, ino, req->offset, req->len, &req->iov, 1, NodeVitastor::postpone_read_finish, req);
|
||||
}
|
||||
else if (req->op == NODE_VITASTOR_WRITE)
|
||||
{
|
||||
cli->Ref();
|
||||
std::unique_lock<std::mutex> lock(cli->mu);
|
||||
uint64_t ino = vitastor_c_inode_get_num(watch);
|
||||
vitastor_c_write(cli->c, ino, req->offset, req->len, req->version,
|
||||
req->iov_list.size() ? req->iov_list.data() : &req->iov,
|
||||
req->iov_list.size() ? req->iov_list.size() : 1,
|
||||
NodeVitastor::on_write_finish, req);
|
||||
NodeVitastor::postpone_write_finish, req);
|
||||
}
|
||||
else if (req->op == NODE_VITASTOR_SYNC)
|
||||
{
|
||||
cli->Ref();
|
||||
std::unique_lock<std::mutex> lock(cli->mu);
|
||||
uint64_t ino = vitastor_c_inode_get_num(watch);
|
||||
uint32_t imm = vitastor_c_inode_get_immediate_commit(cli->c, ino);
|
||||
if (imm != IMMEDIATE_ALL)
|
||||
{
|
||||
vitastor_c_sync(cli->c, NodeVitastor::on_write_finish, req);
|
||||
vitastor_c_sync(cli->c, NodeVitastor::postpone_write_finish, req);
|
||||
}
|
||||
else
|
||||
{
|
||||
NodeVitastor::on_write_finish(req, 0);
|
||||
NodeVitastor::postpone_write_finish(req, 0);
|
||||
}
|
||||
}
|
||||
else if (req->op == NODE_VITASTOR_READ_BITMAP)
|
||||
{
|
||||
cli->Ref();
|
||||
std::unique_lock<std::mutex> lock(cli->mu);
|
||||
uint64_t ino = vitastor_c_inode_get_num(watch);
|
||||
vitastor_c_read_bitmap(cli->c, ino, req->offset, req->len, req->with_parents, NodeVitastor::on_read_bitmap_finish, req);
|
||||
vitastor_c_read_bitmap(cli->c, ino, req->offset, req->len, req->with_parents, NodeVitastor::postpone_read_bitmap_finish, req);
|
||||
}
|
||||
else if (req->op == NODE_VITASTOR_GET_INFO)
|
||||
{
|
||||
uint64_t size = vitastor_c_inode_get_size(watch);
|
||||
uint64_t num = vitastor_c_inode_get_num(watch);
|
||||
uint32_t block_size = vitastor_c_inode_get_block_size(cli->c, num);
|
||||
uint32_t bitmap_granularity = vitastor_c_inode_get_bitmap_granularity(cli->c, num);
|
||||
int readonly = vitastor_c_inode_get_readonly(watch);
|
||||
uint32_t immediate_commit = vitastor_c_inode_get_immediate_commit(cli->c, num);
|
||||
uint64_t parent_id = vitastor_c_inode_get_parent_id(watch);
|
||||
char *meta = vitastor_c_inode_get_meta(watch);
|
||||
uint64_t mod_revision = vitastor_c_inode_get_mod_revision(watch);
|
||||
v8::Local<v8::Object> res = Nan::New<v8::Object>();
|
||||
|
||||
fill_info(res);
|
||||
|
||||
Nan::HandleScope scope;
|
||||
|
||||
v8::Local<v8::Object> res = Nan::New<v8::Object>();
|
||||
Nan::Set(res, Nan::New<v8::String>("pool_id").ToLocalChecked(), Nan::New<v8::Number>(INODE_POOL(num)));
|
||||
Nan::Set(res, Nan::New<v8::String>("inode_num").ToLocalChecked(), Nan::New<v8::Number>(INODE_NO_POOL(num)));
|
||||
if (size < ((uint64_t)1<<53))
|
||||
Nan::Set(res, Nan::New<v8::String>("size").ToLocalChecked(), Nan::New<v8::Number>(size));
|
||||
else
|
||||
Nan::Set(res, Nan::New<v8::String>("size").ToLocalChecked(), v8::BigInt::NewFromUnsigned(v8::Isolate::GetCurrent(), size));
|
||||
if (parent_id)
|
||||
{
|
||||
Nan::Set(res, Nan::New<v8::String>("parent_pool_id").ToLocalChecked(), Nan::New<v8::Number>(INODE_POOL(parent_id)));
|
||||
Nan::Set(res, Nan::New<v8::String>("parent_inode_num").ToLocalChecked(), Nan::New<v8::Number>(INODE_NO_POOL(parent_id)));
|
||||
}
|
||||
Nan::Set(res, Nan::New<v8::String>("readonly").ToLocalChecked(), Nan::New((bool)readonly));
|
||||
if (meta)
|
||||
{
|
||||
Nan::JSON nanJSON;
|
||||
Nan::Set(res, Nan::New<v8::String>("meta").ToLocalChecked(), nanJSON.Parse(Nan::New<v8::String>(meta).ToLocalChecked()).ToLocalChecked());
|
||||
}
|
||||
if (mod_revision < ((uint64_t)1<<53))
|
||||
Nan::Set(res, Nan::New<v8::String>("mod_revision").ToLocalChecked(), Nan::New<v8::Number>(mod_revision));
|
||||
else
|
||||
Nan::Set(res, Nan::New<v8::String>("mod_revision").ToLocalChecked(), v8::BigInt::NewFromUnsigned(v8::Isolate::GetCurrent(), mod_revision));
|
||||
Nan::Set(res, Nan::New<v8::String>("block_size").ToLocalChecked(), Nan::New(block_size));
|
||||
Nan::Set(res, Nan::New<v8::String>("bitmap_granularity").ToLocalChecked(), Nan::New(bitmap_granularity));
|
||||
Nan::Set(res, Nan::New<v8::String>("immediate_commit").ToLocalChecked(), Nan::New(immediate_commit));
|
||||
|
||||
Nan::Callback nanCallback(Nan::New(req->callback));
|
||||
v8::Local<v8::Value> args[1];
|
||||
args[0] = res;
|
||||
@@ -512,6 +548,46 @@ void NodeVitastorImage::exec_request(NodeVitastorRequest *req)
|
||||
|
||||
delete req;
|
||||
}
|
||||
cli->run_postponed();
|
||||
}
|
||||
|
||||
void NodeVitastorImage::fill_info(v8::Local<v8::Object> & res)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(cli->mu);
|
||||
uint64_t size = vitastor_c_inode_get_size(watch);
|
||||
uint64_t num = vitastor_c_inode_get_num(watch);
|
||||
uint32_t block_size = vitastor_c_inode_get_block_size(cli->c, num);
|
||||
uint32_t bitmap_granularity = vitastor_c_inode_get_bitmap_granularity(cli->c, num);
|
||||
int readonly = vitastor_c_inode_get_readonly(watch);
|
||||
uint32_t immediate_commit = vitastor_c_inode_get_immediate_commit(cli->c, num);
|
||||
uint64_t parent_id = vitastor_c_inode_get_parent_id(watch);
|
||||
char *meta = vitastor_c_inode_get_meta(watch);
|
||||
uint64_t mod_revision = vitastor_c_inode_get_mod_revision(watch);
|
||||
|
||||
Nan::Set(res, Nan::New<v8::String>("pool_id").ToLocalChecked(), Nan::New<v8::Number>(INODE_POOL(num)));
|
||||
Nan::Set(res, Nan::New<v8::String>("inode_num").ToLocalChecked(), Nan::New<v8::Number>(INODE_NO_POOL(num)));
|
||||
if (size < ((uint64_t)1<<53))
|
||||
Nan::Set(res, Nan::New<v8::String>("size").ToLocalChecked(), Nan::New<v8::Number>(size));
|
||||
else
|
||||
Nan::Set(res, Nan::New<v8::String>("size").ToLocalChecked(), v8::BigInt::NewFromUnsigned(v8::Isolate::GetCurrent(), size));
|
||||
if (parent_id)
|
||||
{
|
||||
Nan::Set(res, Nan::New<v8::String>("parent_pool_id").ToLocalChecked(), Nan::New<v8::Number>(INODE_POOL(parent_id)));
|
||||
Nan::Set(res, Nan::New<v8::String>("parent_inode_num").ToLocalChecked(), Nan::New<v8::Number>(INODE_NO_POOL(parent_id)));
|
||||
}
|
||||
Nan::Set(res, Nan::New<v8::String>("readonly").ToLocalChecked(), Nan::New((bool)readonly));
|
||||
if (meta)
|
||||
{
|
||||
Nan::JSON nanJSON;
|
||||
Nan::Set(res, Nan::New<v8::String>("meta").ToLocalChecked(), nanJSON.Parse(Nan::New<v8::String>(meta).ToLocalChecked()).ToLocalChecked());
|
||||
}
|
||||
if (mod_revision < ((uint64_t)1<<53))
|
||||
Nan::Set(res, Nan::New<v8::String>("mod_revision").ToLocalChecked(), Nan::New<v8::Number>(mod_revision));
|
||||
else
|
||||
Nan::Set(res, Nan::New<v8::String>("mod_revision").ToLocalChecked(), v8::BigInt::NewFromUnsigned(v8::Isolate::GetCurrent(), mod_revision));
|
||||
Nan::Set(res, Nan::New<v8::String>("block_size").ToLocalChecked(), Nan::New(block_size));
|
||||
Nan::Set(res, Nan::New<v8::String>("bitmap_granularity").ToLocalChecked(), Nan::New(bitmap_granularity));
|
||||
Nan::Set(res, Nan::New<v8::String>("immediate_commit").ToLocalChecked(), Nan::New(immediate_commit));
|
||||
}
|
||||
|
||||
void NodeVitastorImage::on_watch_start(void *opaque, long retval)
|
||||
@@ -532,6 +608,8 @@ void NodeVitastorImage::on_watch_start(void *opaque, long retval)
|
||||
// NodeVitastorKV
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
Nan::Persistent<v8::Function> NodeVitastorKV::listing_class;
|
||||
|
||||
// constructor(node_vitastor)
|
||||
NAN_METHOD(NodeVitastorKV::Create)
|
||||
{
|
||||
@@ -548,24 +626,26 @@ NAN_METHOD(NodeVitastorKV::Create)
|
||||
}
|
||||
|
||||
kv->Wrap(info.This());
|
||||
cli->Ref();
|
||||
info.GetReturnValue().Set(info.This());
|
||||
}
|
||||
|
||||
NodeVitastorKV::~NodeVitastorKV()
|
||||
{
|
||||
delete dbw;
|
||||
cli->Unref();
|
||||
}
|
||||
|
||||
// open(inode_id, { ...config }, callback(err))
|
||||
// open(pool_id, inode_num, { ...config }, callback(err))
|
||||
NAN_METHOD(NodeVitastorKV::Open)
|
||||
{
|
||||
TRACE("NodeVitastorKV::Open");
|
||||
|
||||
NodeVitastorKV* kv = Nan::ObjectWrap::Unwrap<NodeVitastorKV>(info.This());
|
||||
|
||||
uint64_t inode_id = Nan::To<int64_t>(info[0]).FromJust();
|
||||
uint64_t inode_id = INODE_WITH_POOL(Nan::To<int64_t>(info[0]).FromJust(), Nan::To<int64_t>(info[1]).FromJust());
|
||||
|
||||
v8::Local<v8::Object> jsParams = info[1].As<v8::Object>();
|
||||
v8::Local<v8::Object> jsParams = info[2].As<v8::Object>();
|
||||
v8::Local<v8::Array> keys = Nan::GetOwnPropertyNames(jsParams).ToLocalChecked();
|
||||
std::map<std::string, std::string> cfg;
|
||||
for (uint32_t i = 0; i < keys->Length(); i++)
|
||||
@@ -574,8 +654,8 @@ NAN_METHOD(NodeVitastorKV::Open)
|
||||
cfg[std::string(*Nan::Utf8String(key))] = std::string(*Nan::Utf8String(Nan::Get(jsParams, key).ToLocalChecked()));
|
||||
}
|
||||
|
||||
v8::Local<v8::Function> callback = info[2].As<v8::Function>();
|
||||
auto req = new NodeVitastorRequest(callback);
|
||||
v8::Local<v8::Function> callback = info[3].As<v8::Function>();
|
||||
auto req = new NodeVitastorRequest(kv->cli, callback);
|
||||
|
||||
kv->Ref();
|
||||
kv->dbw->open(inode_id, cfg, [kv, req](int res)
|
||||
@@ -598,7 +678,7 @@ NAN_METHOD(NodeVitastorKV::Close)
|
||||
NodeVitastorKV* kv = Nan::ObjectWrap::Unwrap<NodeVitastorKV>(info.This());
|
||||
|
||||
v8::Local<v8::Function> callback = info[0].As<v8::Function>();
|
||||
auto req = new NodeVitastorRequest(callback);
|
||||
auto req = new NodeVitastorRequest(kv->cli, callback);
|
||||
|
||||
kv->Ref();
|
||||
kv->dbw->close([kv, req]()
|
||||
@@ -651,7 +731,7 @@ void NodeVitastorKV::get_impl(const Nan::FunctionCallbackInfo<v8::Value> & info,
|
||||
std::string key(*Nan::Utf8String(info[0].As<v8::String>()));
|
||||
|
||||
v8::Local<v8::Function> callback = info[1].As<v8::Function>();
|
||||
auto req = new NodeVitastorRequest(callback);
|
||||
auto req = new NodeVitastorRequest(kv->cli, callback);
|
||||
|
||||
kv->Ref();
|
||||
kv->dbw->get(key, [kv, req](int res, const std::string & value)
|
||||
@@ -708,13 +788,13 @@ NAN_METHOD(NodeVitastorKV::Set)
|
||||
std::string value(*Nan::Utf8String(info[1].As<v8::String>()));
|
||||
|
||||
v8::Local<v8::Function> callback = info[2].As<v8::Function>();
|
||||
NodeVitastorRequest *req = new NodeVitastorRequest(callback), *cas_req = NULL;
|
||||
NodeVitastorRequest *req = new NodeVitastorRequest(kv->cli, callback), *cas_req = NULL;
|
||||
|
||||
std::function<bool(int, const std::string &)> cas_cb;
|
||||
if (info.Length() > 3 && info[3]->IsObject())
|
||||
{
|
||||
v8::Local<v8::Function> cas_callback = info[3].As<v8::Function>();
|
||||
cas_req = new NodeVitastorRequest(cas_callback);
|
||||
cas_req = new NodeVitastorRequest(kv->cli, cas_callback);
|
||||
cas_cb = make_cas_callback(cas_req);
|
||||
}
|
||||
|
||||
@@ -744,13 +824,13 @@ NAN_METHOD(NodeVitastorKV::Del)
|
||||
std::string key(*Nan::Utf8String(info[0].As<v8::String>()));
|
||||
|
||||
v8::Local<v8::Function> callback = info[1].As<v8::Function>();
|
||||
NodeVitastorRequest *req = new NodeVitastorRequest(callback), *cas_req = NULL;
|
||||
NodeVitastorRequest *req = new NodeVitastorRequest(kv->cli, callback), *cas_req = NULL;
|
||||
|
||||
std::function<bool(int, const std::string &)> cas_cb;
|
||||
if (info.Length() > 2 && info[2]->IsObject())
|
||||
{
|
||||
v8::Local<v8::Function> cas_callback = info[2].As<v8::Function>();
|
||||
cas_req = new NodeVitastorRequest(cas_callback);
|
||||
cas_req = new NodeVitastorRequest(kv->cli, cas_callback);
|
||||
cas_cb = make_cas_callback(cas_req);
|
||||
}
|
||||
|
||||
@@ -786,6 +866,15 @@ NAN_METHOD(NodeVitastorKV::List)
|
||||
info.GetReturnValue().Set(Nan::NewInstance(cons, narg, args).ToLocalChecked());
|
||||
}
|
||||
|
||||
/*NAN_METHOD(NodeVitastorKV::Destroy)
|
||||
{
|
||||
TRACE("NodeVitastorKV::Destroy");
|
||||
NodeVitastorKV* kv = Nan::ObjectWrap::Unwrap<NodeVitastorKV>(info.This());
|
||||
std::unique_lock<std::mutex> lock(self->mu);
|
||||
if (!kv->dead)
|
||||
kv->Unref();
|
||||
}*/
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// NodeVitastorKVListing
|
||||
//////////////////////////////////////////////////
|
||||
@@ -813,6 +902,7 @@ NAN_METHOD(NodeVitastorKVListing::Create)
|
||||
}
|
||||
|
||||
list->Wrap(info.This());
|
||||
kv->Ref();
|
||||
info.GetReturnValue().Set(info.This());
|
||||
}
|
||||
|
||||
@@ -824,6 +914,7 @@ NodeVitastorKVListing::~NodeVitastorKVListing()
|
||||
kv->dbw->list_close(handle);
|
||||
handle = NULL;
|
||||
}
|
||||
kv->Unref();
|
||||
}
|
||||
|
||||
// next(callback(err, value))
|
||||
@@ -834,7 +925,7 @@ NAN_METHOD(NodeVitastorKVListing::Next)
|
||||
NodeVitastorKVListing* list = Nan::ObjectWrap::Unwrap<NodeVitastorKVListing>(info.This());
|
||||
|
||||
v8::Local<v8::Function> callback = info[0].As<v8::Function>();
|
||||
auto req = new NodeVitastorRequest(callback);
|
||||
auto req = new NodeVitastorRequest(list->kv->cli, callback);
|
||||
if (!list->handle)
|
||||
{
|
||||
// Already closed
|
||||
|
||||
+11
-7
@@ -36,6 +36,7 @@ private:
|
||||
uv_poll_t poll_watcher;
|
||||
// FIXME: Is it really needed?
|
||||
std::mutex mu;
|
||||
std::vector<std::function<void()>> postponed;
|
||||
|
||||
NodeVitastor();
|
||||
|
||||
@@ -44,6 +45,14 @@ private:
|
||||
static void on_write_finish(void *opaque, long retval);
|
||||
static void on_read_bitmap_finish(void *opaque, long retval, uint8_t *bitmap);
|
||||
|
||||
void run_postponed();
|
||||
static void postpone_read_finish(void *opaque, long retval, uint64_t version);
|
||||
static void postpone_write_finish(void *opaque, long retval);
|
||||
static void postpone_read_bitmap_finish(void *opaque, long retval, uint8_t *bitmap);
|
||||
|
||||
NodeVitastorRequest* get_read_request(const Nan::FunctionCallbackInfo<v8::Value> & info, int argpos);
|
||||
NodeVitastorRequest* get_write_request(const Nan::FunctionCallbackInfo<v8::Value> & info, int argpos);
|
||||
|
||||
friend class NodeVitastorImage;
|
||||
friend class NodeVitastorKV;
|
||||
friend class NodeVitastorKVListing;
|
||||
@@ -74,11 +83,10 @@ private:
|
||||
std::vector<NodeVitastorRequest*> on_init;
|
||||
Nan::Persistent<v8::Object> cliObj;
|
||||
|
||||
NodeVitastorImage();
|
||||
|
||||
static void on_watch_start(void *opaque, long retval);
|
||||
void exec_request(NodeVitastorRequest *req);
|
||||
void exec_or_wait(NodeVitastorRequest *req);
|
||||
void fill_info(v8::Local<v8::Object> & res);
|
||||
};
|
||||
|
||||
class NodeVitastorKV: public Nan::ObjectWrap
|
||||
@@ -86,7 +94,7 @@ class NodeVitastorKV: public Nan::ObjectWrap
|
||||
public:
|
||||
// constructor(node_vitastor)
|
||||
static NAN_METHOD(Create);
|
||||
// open(inode_id, { ...config }, callback(err))
|
||||
// open(pool_id, inode_num, { ...config }, callback(err))
|
||||
static NAN_METHOD(Open);
|
||||
// set_config({ ...config })
|
||||
static NAN_METHOD(SetConfig);
|
||||
@@ -113,8 +121,6 @@ private:
|
||||
NodeVitastor *cli = NULL;
|
||||
vitastorkv_dbw_t *dbw = NULL;
|
||||
|
||||
NodeVitastorKV();
|
||||
|
||||
static void get_impl(const Nan::FunctionCallbackInfo<v8::Value> & info, bool allow_cache);
|
||||
|
||||
friend class NodeVitastorKVListing;
|
||||
@@ -135,8 +141,6 @@ public:
|
||||
private:
|
||||
NodeVitastorKV *kv = NULL;
|
||||
void *handle = NULL;
|
||||
|
||||
NodeVitastorKVListing();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require('bindings')('addon.node');
|
||||
Reference in New Issue
Block a user