Skip to content

Commit a1869a6

Browse files
committed
feat: enable Draft API support
1 parent 9d69b11 commit a1869a6

File tree

5 files changed

+59
-40
lines changed

5 files changed

+59
-40
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ macro(set_option_from_env OPTION_NAME)
2828
message(STATUS "${OPTION_NAME}: ${${OPTION_NAME}}")
2929
endmacro()
3030

31-
option(ZMQ_DRAFT "Build and install draft APIs" OFF)
31+
option(ZMQ_DRAFT "Build and install draft APIs (e.g. `server-client`, `radio-dish`, `scatter-gather`)" ON)
3232
set_option_from_env(ZMQ_DRAFT)
3333

3434
option(ZMQ_CURVE "Enable CURVE security" ON)

README.md

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
- High performance.
1212
- Fully usable with TypeScript (3+).
1313
- Compatible with Zeromq 4/5 via "zeromq/v5-compat"
14+
- Secure Curve protocol support
15+
- Zeromq Draft API support
1416

1517
## Useful links
1618

@@ -28,7 +30,7 @@
2830
- [Installation](#installation)
2931
- [Prebuilt binaries](#prebuilt-binaries)
3032
- [Building from source](#building-from-source)
31-
- [Available Build Options](#available-build-options)
33+
- [Available Build Options](#available-build-options)
3234
- [Curve with Libsodium support](#curve-with-libsodium-support)
3335
- [Draft support](#draft-support)
3436
- [Websocket support](#websocket-support)
@@ -104,31 +106,38 @@ source:
104106

105107
To install from source, specify `build_from_source=true` in a `.npmrc` file
106108

107-
```
109+
```ini
108110
build_from_source=true
109111
```
110112

113+
#### Available Build Options
114+
111115
When building from source, you can also specify additional build options in a
112116
`.npmrc` file in your project:
113117

114-
### Available Build Options
115-
116118
<details>
117119
<summary>👉🏻 Options</summary>
118120

119121
### Curve with Libsodium support
120122

121-
Enables CURVE security for encrypted communications. Zeromq uses libsodium for CURVE security. To enable CURVE support, add the following to your .npmrc:
123+
(Enabled by default)
124+
125+
Enables CURVE security for encrypted communications. Zeromq uses libsodium for
126+
CURVE security. To enable CURVE support, add the following to your .npmrc:
122127

123128
```ini
124129
zmq_curve="true"
125130
zmq_sodium="true"
126131
```
127132

128-
Building libsodium requires these dependencies on Linux/MacOS: `autoconf automake libtool`, which can be installed via `apt-get` or `brew`, etc.
133+
Building libsodium requires these dependencies on Linux/MacOS:
134+
`autoconf automake libtool`, which can be installed via `apt-get` or `brew`,
135+
etc.
129136

130137
#### Draft support
131138

139+
(Enabled by default)
140+
132141
By default `libzmq` is built with support for `Draft` patterns (e.g.
133142
`server-client`, `radio-dish`, `scatter-gather`). If you want to build `libzmq`
134143
without support for `Draft`, you can specify the following in `.npmrc`:

src/module.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ struct Terminator {
3232
});
3333

3434
using namespace std::chrono_literals;
35-
if (terminate.wait_for(500ms) == std::future_status::timeout) {
35+
const auto timeout = 500ms;
36+
if (terminate.wait_for(timeout) == std::future_status::timeout) {
3637
/* We can't use process.emitWarning, because the Node.js runtime
3738
has already shut down. So we mimic it instead. */
3839
(void)fprintf(stderr,

src/outgoing_msg.cc

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -121,18 +121,18 @@ bool OutgoingMsg::Parts::SetGroup(Napi::Value value) {
121121
auto group = [&]() {
122122
if (value.IsString()) {
123123
return std::string(value.As<Napi::String>());
124-
} else if (value.IsBuffer()) {
125-
Napi::Object buf = value.As<Napi::Object>();
124+
}
125+
if (value.IsBuffer()) {
126+
auto buf = value.As<Napi::Object>();
126127
auto length = buf.As<Napi::Buffer<char>>().Length();
127-
auto value = buf.As<Napi::Buffer<char>>().Data();
128+
auto* value = buf.As<Napi::Buffer<char>>().Data();
128129
return std::string(value, length);
129-
} else {
130-
return std::string();
131130
}
131+
return std::string();
132132
}();
133133

134134
for (auto& part : parts) {
135-
if (zmq_msg_set_group(part, group.c_str()) < 0) {
135+
if (zmq_msg_set_group(part.get(), group.c_str()) < 0) {
136136
ErrnoException(value.Env(), zmq_errno()).ThrowAsJavaScriptException();
137137
return false;
138138
}
@@ -142,15 +142,15 @@ bool OutgoingMsg::Parts::SetGroup(Napi::Value value) {
142142
}
143143

144144
bool OutgoingMsg::Parts::SetRoutingId(Napi::Value value) {
145-
if (value.IsUndefined()) {
145+
if (value.IsUndefined()) {https://clang.llvm.org/extra/clang-tidy/checks/readability/identifier-length.html
146146
ErrnoException(value.Env(), EINVAL).ThrowAsJavaScriptException();
147147
return false;
148148
}
149149

150-
auto id = value.As<Napi::Number>().Uint32Value();
150+
auto routing_id = value.As<Napi::Number>().Uint32Value();
151151

152152
for (auto& part : parts) {
153-
if (zmq_msg_set_routing_id(part, id) < 0) {
153+
if (zmq_msg_set_routing_id(part.get(), routing_id) < 0) {
154154
ErrnoException(value.Env(), zmq_errno()).ThrowAsJavaScriptException();
155155
return false;
156156
}

src/socket.cc

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ Socket::Socket(const Napi::CallbackInfo& info)
103103
}
104104

105105
uv_os_sock_t file_descriptor = 0;
106-
std::function<void()> const finalize = nullptr;
107106

108107
const auto error = [this]() {
109108
[[maybe_unused]] auto err = zmq_close(socket);
@@ -125,20 +124,22 @@ Socket::Socket(const Napi::CallbackInfo& info)
125124
}
126125
#endif
127126

127+
std::function<void()> finalize = nullptr;
128+
128129
/* Currently only some DRAFT sockets are threadsafe. */
129130
if (thread_safe) {
130131
#ifdef ZMQ_HAS_POLLABLE_THREAD_SAFE
131132
/* Threadsafe sockets do not expose an FD we can integrate into the
132133
event loop, so we have to construct one by creating a zmq_poller. */
133-
auto poll = zmq_poller_new();
134+
auto* poll = zmq_poller_new();
134135
if (poll == nullptr) {
135136
ErrnoException(Env(), zmq_errno()).ThrowAsJavaScriptException();
136137
error();
137138
}
138139

139140
/* Callback to free the underlying poller. Move the poller to transfer
140141
ownership after the constructor has completed. */
141-
finalize = [=]() mutable {
142+
finalize = [&]() {
142143
[[maybe_unused]] auto err = zmq_poller_destroy(&poll);
143144
assert(err == 0);
144145
};
@@ -149,7 +150,7 @@ Socket::Socket(const Napi::CallbackInfo& info)
149150
error();
150151
}
151152

152-
if (zmq_poller_fd(poll, &fd) < 0) {
153+
if (zmq_poller_fd(poll, &file_descriptor) < 0) {
153154
ErrnoException(Env(), zmq_errno()).ThrowAsJavaScriptException();
154155
finalize();
155156
error();
@@ -327,17 +328,17 @@ void Socket::Receive(const Napi::Promise::Deferred& res) {
327328
switch (type) {
328329
case ZMQ_SERVER: {
329330
auto meta = Napi::Object::New(Env());
330-
meta.Set("routingId", zmq_msg_routing_id(part));
331-
list[i++] = meta;
331+
meta.Set("routingId", zmq_msg_routing_id(part.get()));
332+
list[i_part++] = meta;
332333
break;
333334
}
334335

335336
case ZMQ_DISH: {
336337
auto meta = Napi::Object::New(Env());
337-
auto data = zmq_msg_group(part);
338+
const auto* data = zmq_msg_group(part.get());
338339
auto length = strnlen(data, ZMQ_GROUP_MAX_LENGTH);
339340
meta.Set("group", Napi::Buffer<char>::Copy(Env(), data, length));
340-
list[i++] = meta;
341+
list[i_part++] = meta;
341342
break;
342343
}
343344
}
@@ -534,7 +535,9 @@ Napi::Value Socket::Send(const Napi::CallbackInfo& info) {
534535
Arg::Required<Arg::Object>("Options must be an object"),
535536
};
536537

537-
if (args.ThrowIfInvalid(info)) return Env().Undefined();
538+
if (args.ThrowIfInvalid(info)) {
539+
return Env().Undefined();
540+
}
538541

539542
break;
540543
}
@@ -676,19 +679,22 @@ void Socket::Join([[maybe_unused]] const Napi::CallbackInfo& info) {
676679
Arg::Required<Arg::String, Arg::Buffer>("Group must be a string or buffer"),
677680
};
678681

679-
if (args.ThrowIfInvalid(info)) return;
682+
if (args.ThrowIfInvalid(info)) {
683+
return;
684+
}
680685

681-
if (!ValidateOpen()) return;
686+
if (!ValidateOpen()) {
687+
return;
688+
}
682689

683690
auto str = [&]() {
684691
if (info[0].IsString()) {
685692
return std::string(info[0].As<Napi::String>());
686-
} else {
687-
Napi::Object buf = info[0].As<Napi::Object>();
688-
auto length = buf.As<Napi::Buffer<char>>().Length();
689-
auto value = buf.As<Napi::Buffer<char>>().Data();
690-
return std::string(value, length);
691693
}
694+
auto buf = info[0].As<Napi::Object>();
695+
auto length = buf.As<Napi::Buffer<char>>().Length();
696+
auto* value = buf.As<Napi::Buffer<char>>().Data();
697+
return std::string(value, length);
692698
}();
693699

694700
if (zmq_join(socket, str.c_str()) < 0) {
@@ -704,19 +710,22 @@ void Socket::Leave([[maybe_unused]] const Napi::CallbackInfo& info) {
704710
Arg::Required<Arg::String, Arg::Buffer>("Group must be a string or buffer"),
705711
};
706712

707-
if (args.ThrowIfInvalid(info)) return;
713+
if (args.ThrowIfInvalid(info)) {
714+
return;
715+
}
708716

709-
if (!ValidateOpen()) return;
717+
if (!ValidateOpen()) {
718+
return;
719+
}
710720

711721
auto str = [&]() {
712722
if (info[0].IsString()) {
713723
return std::string(info[0].As<Napi::String>());
714-
} else {
715-
Napi::Object buf = info[0].As<Napi::Object>();
716-
auto length = buf.As<Napi::Buffer<char>>().Length();
717-
auto value = buf.As<Napi::Buffer<char>>().Data();
718-
return std::string(value, length);
719724
}
725+
auto buf = info[0].As<Napi::Object>();
726+
auto length = buf.As<Napi::Buffer<char>>().Length();
727+
auto* value = buf.As<Napi::Buffer<char>>().Data();
728+
return std::string(value, length);
720729
}();
721730

722731
if (zmq_leave(socket, str.c_str()) < 0) {

0 commit comments

Comments
 (0)