nats.zig/src/connection.zig

539 lines
22 KiB
Zig
Raw Normal View History

const std = @import("std");
pub const nats_c = @cImport({
@cInclude("nats/nats.h");
});
const sub_ = @import("./subscription.zig");
const Subscription = sub_.Subscription;
const SubscriptionThunkCallback = sub_.SubscriptionThunkCallback;
const subscriptionMessageThunk = sub_.subscriptionMessageThunk;
const msg_ = @import("./message.zig");
const Message = msg_.Message;
const err_ = @import("./error.zig");
const Error = err_.Error;
const Status = err_.Status;
pub const default_server_url: [:0]const u8 = nats_c.NATS_DEFAULT_URL;
pub const Connection = opaque {
pub fn connect(options: *ConnectionOptions) Error!*Connection {
var self: *Connection = undefined;
const status = Status.fromInt(nats_c.natsConnection_Connect(@ptrCast(&self), @ptrCast(options)));
return status.toError() orelse self;
}
pub fn connectTo(urls: [:0]const u8) Error!*Connection {
var self: *Connection = undefined;
const status = Status.fromInt(
nats_c.natsConnection_ConnectTo(@ptrCast(&self), urls.ptr),
);
return status.toError() orelse self;
}
pub fn close(self: *Connection) void {
return nats_c.natsConnection_Close(@ptrCast(self));
}
pub fn destroy(self: *Connection) void {
return nats_c.natsConnection_Destroy(@ptrCast(self));
}
pub fn publishString(
self: *Connection,
subject: [:0]const u8,
message: [:0]const u8,
) Error!void {
const status = Status.fromInt(nats_c.natsConnection_PublishString(
@ptrCast(self),
subject,
message,
));
return status.raise();
}
pub fn requestString(
self: *Connection,
subject: [:0]const u8,
request: [:0]const u8,
timeout: i64,
) Error!*Message {
var msg: *Message = undefined;
const status = Status.fromInt(nats_c.natsConnection_RequestString(
@ptrCast(&msg),
@ptrCast(self),
subject,
request,
timeout,
));
return status.toError() orelse msg;
}
pub fn subscribe(
self: *Connection,
comptime T: type,
subject: [:0]const u8,
callback: SubscriptionThunkCallback(T),
userdata: *T,
) Error!*Subscription {
var sub: *Subscription = undefined;
const status = Status.fromInt(nats_c.natsConnection_Subscribe(
@ptrCast(&sub),
@ptrCast(self),
subject,
subscriptionMessageThunk(T, callback),
userdata,
));
return status.toError() orelse sub;
}
};
// NATS_EXTERN void natsConnection_ProcessReadEvent(natsConnection *nc);
// NATS_EXTERN void natsConnection_ProcessWriteEvent(natsConnection *nc);
// NATS_EXTERN bool natsConnection_IsClosed(natsConnection *nc);
// NATS_EXTERN bool natsConnection_IsReconnecting(natsConnection *nc);
// NATS_EXTERN natsConnStatus natsConnection_Status(natsConnection *nc);
// NATS_EXTERN int natsConnection_Buffered(natsConnection *nc);
// NATS_EXTERN natsStatus natsConnection_Flush(natsConnection *nc);
// NATS_EXTERN natsStatus natsConnection_FlushTimeout(natsConnection *nc, int64_t timeout);
// NATS_EXTERN int64_t natsConnection_GetMaxPayload(natsConnection *nc);
// NATS_EXTERN natsStatus natsConnection_GetStats(natsConnection *nc, natsStatistics *stats);
// NATS_EXTERN natsStatus natsConnection_GetConnectedUrl(natsConnection *nc, char *buffer, size_t bufferSize);
// NATS_EXTERN natsStatus natsConnection_GetConnectedServerId(natsConnection *nc, char *buffer, size_t bufferSize);
// NATS_EXTERN natsStatus natsConnection_GetServers(natsConnection *nc, char ***servers, int *count);
// NATS_EXTERN natsStatus natsConnection_GetDiscoveredServers(natsConnection *nc, char ***servers, int *count);
// NATS_EXTERN natsStatus natsConnection_GetLastError(natsConnection *nc, const char **lastError);
// NATS_EXTERN natsStatus natsConnection_GetClientID(natsConnection *nc, uint64_t *cid);
// NATS_EXTERN natsStatus natsConnection_Drain(natsConnection *nc);
// NATS_EXTERN natsStatus natsConnection_DrainTimeout(natsConnection *nc, int64_t timeout);
// NATS_EXTERN natsStatus natsConnection_Sign(natsConnection *nc, const unsigned char *message, int messageLen, unsigned char sig[64]);
// NATS_EXTERN natsStatus natsConnection_GetClientIP(natsConnection *nc, char **ip);
// NATS_EXTERN natsStatus natsConnection_GetRTT(natsConnection *nc, int64_t *rtt);
// NATS_EXTERN natsStatus natsConnection_HasHeaderSupport(natsConnection *nc);
// NATS_EXTERN natsStatus natsConnection_Publish(natsConnection *nc, const char *subj, const void *data, int dataLen);
// NATS_EXTERN natsStatus natsConnection_PublishString(natsConnection *nc, const char *subj, const char *str);
// NATS_EXTERN natsStatus natsConnection_PublishMsg(natsConnection *nc, natsMsg *msg);
// NATS_EXTERN natsStatus natsConnection_PublishRequest(natsConnection *nc, const char *subj, const char *reply, const void *data, int dataLen);
// NATS_EXTERN natsStatus natsConnection_PublishRequestString(natsConnection *nc, const char *subj, const char *reply, const char *str);
// NATS_EXTERN natsStatus natsConnection_Request(natsMsg **replyMsg, natsConnection *nc, const char *subj, const void *data, int dataLen, int64_t timeout);
// NATS_EXTERN natsStatus natsConnection_RequestString(natsMsg **replyMsg, natsConnection *nc, const char *subj, const char *str, int64_t timeout);
// NATS_EXTERN natsStatus natsConnection_RequestMsg(natsMsg **replyMsg, natsConnection *nc,natsMsg *requestMsg, int64_t timeout);
// NATS_EXTERN natsStatus natsConnection_Subscribe(natsSubscription **sub, natsConnection *nc, const char *subject, natsMsgHandler cb, void *cbClosure);
// NATS_EXTERN natsStatus natsConnection_SubscribeTimeout(natsSubscription **sub, natsConnection *nc, const char *subject, int64_t timeout, natsMsgHandler cb, void *cbClosure);
// NATS_EXTERN natsStatus natsConnection_SubscribeSync(natsSubscription **sub, natsConnection *nc, const char *subject);
// NATS_EXTERN natsStatus natsConnection_QueueSubscribe(natsSubscription **sub, natsConnection *nc, const char *subject, const char *queueGroup, natsMsgHandler cb, void *cbClosure);
// NATS_EXTERN natsStatus natsConnection_QueueSubscribeTimeout(natsSubscription **sub, natsConnection *nc, const char *subject, const char *queueGroup, int64_t timeout, natsMsgHandler cb, void *cbClosure);
// NATS_EXTERN natsStatus natsConnection_QueueSubscribeSync(natsSubscription **sub, natsConnection *nc, const char *subject, const char *queueGroup);
//
const ConnectionOptions = opaque {
pub fn create() Error!*ConnectionOptions {
var self: *ConnectionOptions = undefined;
const status = Status.fromInt(nats_c.natsOptions_Create(@ptrCast(&self)));
return status.toError() orelse self;
}
pub fn destroy(self: *ConnectionOptions) void {
nats_c.natsOptions_Destroy(@ptrCast(self));
}
pub fn setUrl(self: *ConnectionOptions, url: [:0]const u8) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetURL(@ptrCast(self), url.ptr),
).raise();
}
pub fn setServers(self: *ConnectionOptions, servers: [][:0]const u8) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetServers(
@ptrCast(self),
servers.ptr,
@intCast(servers.len),
),
).raise();
}
pub fn setCredentials(self: *ConnectionOptions, user: [:0]const u8, password: [:0]const u8) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetUserInfo(
@ptrCast(self),
user.ptr,
password.ptr,
),
).raise();
}
pub fn setToken(self: *ConnectionOptions, token: [:0]const u8) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetToken(@ptrCast(self), token.ptr),
).raise();
}
// needs a simple thunk. same signature as the subscription completion callback and
// could use the same thunk. Perhaps I should move the thunks into a common module?
// typedef const char* (*natsTokenHandler)(void *closure);
// NATS_EXTERN natsStatus natsOptions_SetTokenHandler(natsOptions *opts, natsTokenHandler tokenCb, void *closure);
// pub fn setTokenHandler(self: *ConnectionOptions, comptime T: type, callback: Thunked, userdata: T) Error!void
pub fn setNoRandomize(self: *ConnectionOptions, no: bool) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetNoRandomize(@ptrCast(self), no),
).raise();
}
pub fn setTimeout(self: *ConnectionOptions, timeout: i64) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetTimeout(@ptrCast(self), timeout),
).raise();
}
pub fn setName(self: *ConnectionOptions, name: [:0]const u8) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetName(@ptrCast(self), name.ptr),
).raise();
}
pub fn setSecure(self: *ConnectionOptions, secure: bool) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetSecure(@ptrCast(self), secure),
).raise();
}
pub fn loadCaTrustedCertificates(self: *ConnectionOptions, filename: [:0]const u8) Error!void {
return Status.fromInt(
nats_c.natsOptions_LoadCATrustedCertificates(@ptrCast(self), filename.ptr),
).raise();
}
pub fn setCaTrustedCertificates(self: *ConnectionOptions, certificates: [:0]const u8) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetCATrustedCertificates(@ptrCast(self), certificates.ptr),
).raise();
}
pub fn loadCertificatesChain(self: *ConnectionOptions, certs_filename: [:0]const u8, key_filename: [:0]const u8) Error!void {
return Status.fromInt(
nats_c.natsOptions_LoadCertificatesChain(@ptrCast(self), certs_filename.ptr, key_filename.ptr),
).raise();
}
pub fn setCertificatesChain(self: *ConnectionOptions, cert: [:0]const u8, key: [:0]const u8) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetCertificatesChain(@ptrCast(self), cert.ptr, key.ptr),
).raise();
}
pub fn setCiphers(self: *ConnectionOptions, ciphers: [:0]const u8) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetSecure(@ptrCast(self), ciphers.ptr),
).raise();
}
pub fn setCipherSuites(self: *ConnectionOptions, ciphers: [:0]const u8) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetSecure(@ptrCast(self), ciphers.ptr),
).raise();
}
pub fn setExpectedHostname(self: *ConnectionOptions, hostname: [:0]const u8) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetExpectedHostname(@ptrCast(self), hostname.ptr),
).raise();
}
pub fn skipServerVerification(self: *ConnectionOptions, skip: bool) Error!void {
return Status.fromInt(
nats_c.natsOptions_SkipServerVerification(@ptrCast(self), skip),
).raise();
}
pub fn setVerbose(self: *ConnectionOptions, verbose: bool) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetVerbose(@ptrCast(self), verbose),
).raise();
}
pub fn setPedantic(self: *ConnectionOptions, pedantic: bool) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetPedantic(@ptrCast(self), pedantic),
).raise();
}
pub fn setPingInterval(self: *ConnectionOptions, interval: i64) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetPingInterval(@ptrCast(self), interval),
).raise();
}
pub fn setMaxPingsOut(self: *ConnectionOptions, max: c_int) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetMaxPingsOut(@ptrCast(self), max),
).raise();
}
pub fn setIoBufSize(self: *ConnectionOptions, size: c_int) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetIOBufSize(@ptrCast(self), size),
).raise();
}
pub fn setAllowReconnect(self: *ConnectionOptions, allow: bool) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetAllowReconnect(@ptrCast(self), allow),
).raise();
}
pub fn setMaxReconnect(self: *ConnectionOptions, max: c_int) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetMaxReconnect(@ptrCast(self), max),
).raise();
}
pub fn setReconnectWait(self: *ConnectionOptions, wait: i64) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetReconnectWait(@ptrCast(self), wait),
).raise();
}
pub fn setReconnectJitter(self: *ConnectionOptions, jitter: i64, jitter_tls: i64) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetReconnectJitter(@ptrCast(self), jitter, jitter_tls),
).raise();
}
// needs a callback thunk
// typedef int64_t (*natsCustomReconnectDelayHandler)(natsConnection *nc, int attempts, void *closure);
// NATS_EXTERN natsStatus natsOptions_SetCustomReconnectDelay(natsOptions *opts, natsCustomReconnectDelayHandler cb, void *closure);
// pub fn setCustomReconnectDelay(self: *ConnectionOptions, max: c_int) Error!void {
// return Status.fromInt(
// nats_c.natsOptions_SetMaxReconnect(@ptrCast(self), max),
// ).raise();
// }
pub fn setReconnectBufSize(self: *ConnectionOptions, size: c_int) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetReconnectBufSize(@ptrCast(self), size),
).raise();
}
pub fn setMaxPendingMessages(self: *ConnectionOptions, max: c_int) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetMaxPendingMsgs(@ptrCast(self), max),
).raise();
}
// needs a callback thunk
// typedef void (*natsErrHandler)(
// natsConnection *nc, natsSubscription *subscription, natsStatus err,
// void *closure);
// NATS_EXTERN natsStatus natsOptions_SetErrorHandler(natsOptions *opts, natsErrHandler errHandler, void *closure);
// pub fn setErrorHandler(self: *ConnectionOptions, max: c_int) Error!void {
// return Status.fromInt(
// nats_c.natsOptions_SetErrorHandler(@ptrCast(self), max),
// ).raise();
// }
// needs a callback thunk
// NATS_EXTERN natsStatus natsOptions_SetClosedCB(natsOptions *opts, natsConnectionHandler closedCb, void *closure);
// typedef void (*natsConnectionHandler)(
// natsConnection *nc, void *closure);
// pub fn setClosedCallback(self: *ConnectionOptions, max: c_int) Error!void {
// return Status.fromInt(
// nats_c.natsOptions_SetClosedCB(@ptrCast(self), max),
// ).raise();
// }
// needs a callback thunk
// NATS_EXTERN natsStatus natsOptions_SetDisconnectedCB(natsOptions *opts, natsConnectionHandler disconnectedCb, void *closure);
// typedef void (*natsConnectionHandler)(
// natsConnection *nc, void *closure);
// pub fn setDisconnectedCallback(self: *ConnectionOptions, max: c_int) Error!void {
// return Status.fromInt(
// nats_c.natsOptions_SetDisconnectedCB(@ptrCast(self), max),
// ).raise();
// }
// needs a callback thunk
// NATS_EXTERN natsStatus natsOptions_SetReconnectedCB(natsOptions *opts, natsConnectionHandler reconnectedCb, void *closure);
// typedef void (*natsConnectionHandler)(
// natsConnection *nc, void *closure);
// pub fn setReconnectedCallback(self: *ConnectionOptions, max: c_int) Error!void {
// return Status.fromInt(
// nats_c.natsOptions_SetReconnectedCB(@ptrCast(self), max),
// ).raise();
// }
// needs a callback thunk
// NATS_EXTERN natsStatus natsOptions_SetDiscoveredServersCB(natsOptions *opts, natsConnectionHandler discoveredServersCb, void *closure);
// typedef void (*natsConnectionHandler)(
// natsConnection *nc, void *closure);
// pub fn setDiscoveredServersCallback(self: *ConnectionOptions, max: c_int) Error!void {
// return Status.fromInt(
// nats_c.natsOptions_SetDiscoveredServersCB(@ptrCast(self), max),
// ).raise();
// }
pub fn ignoreDiscoveredServers(self: *ConnectionOptions, ignore: bool) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetIgnoreDiscoveredServers(@ptrCast(self), ignore),
).raise();
}
// needs a callback thunk
// NATS_EXTERN natsStatus natsOptions_SetLameDuckModeCB(natsOptions *opts, natsConnectionHandler lameDuckCb, void *closure);
// typedef void (*natsConnectionHandler)(
// natsConnection *nc, void *closure);
// pub fn setLameDuckModeCallback(self: *ConnectionOptions, max: c_int) Error!void {
// return Status.fromInt(
// nats_c.natsOptions_SetLameDuckModeCB(@ptrCast(self), max),
// ).raise();
// }
// needs a callback thunk
// NATS_EXTERN natsStatus natsOptions_SetEventLoop(natsOptions *opts, void *loop, natsEvLoop_Attach attachCb, natsEvLoop_ReadAddRemove readCb, natsEvLoop_WriteAddRemove writeCb, natsEvLoop_Detach detachCb);
// typedef natsStatus (*natsEvLoop_Attach)(
// void **userData,
// void *loop,
// natsConnection *nc,
// natsSock socket);
// pub fn setEventLoop(self: *ConnectionOptions, max: c_int) Error!void {
// return Status.fromInt(
// nats_c.natsOptions_SetEventLoop(@ptrCast(self), max),
// ).raise();
// }
pub fn useGlobalMessageDelivery(self: *ConnectionOptions, use: bool) Error!void {
return Status.fromInt(
nats_c.natsOptions_UseGlobalMessageDelivery(@ptrCast(self), use),
).raise();
}
pub const IpResolutionOrder = enum(c_int) {
any_order = 0,
ipv4_only = 4,
ipv6_only = 6,
ipv4_first = 46,
ipv6_first = 64,
};
pub fn ipResolutionOrder(self: *ConnectionOptions, order: IpResolutionOrder) Error!void {
return Status.fromInt(
nats_c.natsOptions_IPResolutionOrder(@ptrCast(self), @intFromEnum(order)),
).raise();
}
pub fn setSendAsap(self: *ConnectionOptions, asap: bool) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetSendAsap(@ptrCast(self), asap),
).raise();
}
pub fn useOldRequestStyle(self: *ConnectionOptions, old: bool) Error!void {
return Status.fromInt(
nats_c.natsOptions_UseOldRequestStyle(@ptrCast(self), old),
).raise();
}
pub fn setFailRequestsOnDisconnect(self: *ConnectionOptions, fail: bool) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetFailRequestsOnDisconnect(@ptrCast(self), fail),
).raise();
}
pub fn setNoEcho(self: *ConnectionOptions, no: bool) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetNoEcho(@ptrCast(self), no),
).raise();
}
// thunkem
// NATS_EXTERN natsStatus natsOptions_SetRetryOnFailedConnect(natsOptions *opts, bool retry, natsConnectionHandler connectedCb, void* closure);
// typedef void (*natsConnectionHandler)(
// natsConnection *nc, void *closure);
// 2 thunk 2 furious
// NATS_EXTERN natsStatus natsOptions_SetUserCredentialsCallbacks(natsOptions *opts, natsUserJWTHandler ujwtCB, void *ujwtClosure, natsSignatureHandler sigCB, void *sigClosure);
// typedef natsStatus (*natsUserJWTHandler)(
// char **userJWT,
// char **customErrTxt,
// void *closure);
// typedef natsStatus (*natsSignatureHandler)(
// char **customErrTxt,
// unsigned char **signature,
// int *signatureLength,
// const char *nonce,
// void *closure);
pub fn setUserCredentialsFromFiles(self: *ConnectionOptions, user_or_chained_file: [:0]const u8, seed_file: [:0]const u8) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetUserCredentialsFromFiles(
@ptrCast(self),
user_or_chained_file.ptr,
seed_file.ptr,
),
).raise();
}
pub fn setUserCredentialsFromMemory(self: *ConnectionOptions, jwt_and_seed: [:0]const u8) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetUserCredentialsFromMemory(
@ptrCast(self),
jwt_and_seed.ptr,
),
).raise();
}
// thunk
// NATS_EXTERN natsStatus natsOptions_SetNKey(natsOptions *opts, const char *pubKey, natsSignatureHandler sigCB, void *sigClosure);
// typedef natsStatus (*natsSignatureHandler)(
// char **customErrTxt,
// unsigned char **signature,
// int *signatureLength,
// const char *nonce,
// void *closure);
pub fn setNKeyFromSeed(self: *ConnectionOptions, pub_key: [:0]const u8, seed_file: [:0]const u8) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetNKeyFromSeed(
@ptrCast(self),
pub_key.ptr,
seed_file.ptr,
),
).raise();
}
pub fn setWriteDeadline(self: *ConnectionOptions, deadline: i64) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetWriteDeadline(@ptrCast(self), deadline),
).raise();
}
pub fn disableNoResponders(self: *ConnectionOptions, no: bool) Error!void {
return Status.fromInt(
nats_c.natsOptions_DisableNoResponders(@ptrCast(self), no),
).raise();
}
pub fn setCustomInboxPrefix(self: *ConnectionOptions, prefix: [:0]const u8) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetCustomInboxPrefix(@ptrCast(self), prefix.ptr),
).raise();
}
pub fn setMessageBufferPadding(self: *ConnectionOptions, padding: c_int) Error!void {
return Status.fromInt(
nats_c.natsOptions_SetMessageBufferPadding(@ptrCast(self), padding),
).raise();
}
};