From c4b4b89e95f3c6bc701a32aba9884ceb3aa118b2 Mon Sep 17 00:00:00 2001 From: gdamore Date: Thu, 2 Jan 2025 03:46:39 +0000 Subject: deploy: f293e96b03b22c6a91140b118c4e15059e285543 --- ref/api/ctx.html | 507 ++++++++++++++++++++++++++++++++++++++++++++++++++++ ref/api/index.html | 1 + ref/api/memory.html | 4 +- ref/api/sock.html | 8 +- 4 files changed, 514 insertions(+), 6 deletions(-) create mode 100644 ref/api/ctx.html (limited to 'ref/api') diff --git a/ref/api/ctx.html b/ref/api/ctx.html new file mode 100644 index 00000000..790efc27 --- /dev/null +++ b/ref/api/ctx.html @@ -0,0 +1,507 @@ + + + + + + Contexts - NNG Reference Manual (DRAFT) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+
+ +

Contexts

+

Contexts in Scalability Protocols provide for isolation of protocol-specific +state machines and associated data, allowing multiple concurrent state machines (or transactions) +to coexist on a single socket.

+

For example, a REP server may wish to allow many requests to be serviced concurrently, +even though some jobs may take significant time to process. Contexts provide for this ability.

+

Not all protocols have contexts, because many protocols simply have no state to manage. +The following protocols support contexts:

+ +

For these protocols, the socket will also have a single, default, context that is used when +performing send or receive operations on the socket directly.

+

Other protocols are stateless, at least with respect to message processing, and have no use for +contexts. For the same reason, raw mode sockets do not support contexts.

+
+

+ + tip +

+

Developers with experience with [libnanomsg] may be used to using raw sockets for concurrency. +Contexts provide a superior solution, as they are much easier to use, less error prone, and allow +for easy control of the amount of concurrency used on any given socket.

+
+

One drawback of contexts is that they cannot be used with file descriptor polling using +nng_socket_get_recv_poll_fd or nng_socket_get_send_poll_fd.

+

Context Structure

+
#define NNG_CTX_INITIALIZER // opaque value
+
+typedef struct nng_ctx_s nng_ctx;
+
+

The nng_ctx structure represents context. This is a handle, and +the members of it are opaque. However, unlike a pointer, it is passed by value.

+

A context may be initialized statically with the NNG_CTX_INITIALIZER macro, +to ensure that it cannot be confused with a valid open context.

+

Creating a Context

+
int nng_ctx_open(nng_ctx *ctxp, nng_socket s);
+
+

The nng_ctx_open function creates a separate context to be used with the socket s, +and returns it at the location pointed by ctxp.

+

Context Identity

+
int nng_ctx_id(nng_ctx c);
+
+

The nng_ctx_id function returns a positive identifier for the context c if it is valid. +Otherwise it returns -1.

+

A context is considered valid if it was ever opened with nng_ctx_open function. +Contexts that are allocated on the stack or statically should be initialized with the macro NNG_CTX_INITIALIZER +to ensure that they cannot be confused with a valid context before they are opened.

+

Closing a Context

+
int nng_ctx_close(nng_ctx ctx);
+
+

The nng_ctx_close function closes the context ctx. +Messages that have been submitted for sending may be flushed or delivered, +depending upon the transport.

+

Further attempts to use the context after this call returns will result in NNG_ECLOSED. +Threads waiting for operations on the context when this +call is executed may also return with an NNG_ECLOSED result.

+
+

+ + note +

+

Closing the socket associated with ctx using nng_socket_close] also closes this context.

+
+

Sending Messages

+
int nng_ctx_sendmsg(nng_ctx ctx, nng_msg *msg, int flags);
+void nng_ctx_send(nng_ctx ctx, nng_aio *aio);
+
+

These functions (nng_ctx_sendmsg and nng_ctx_send) send +messages over the socket s. The differences in their behaviors are as follows.

+
+

+ + note +

+

The semantics of what sending a message means varies from protocol to +protocol, so examination of the protocol documentation is encouraged. +Additionally, some protocols may not support sending at all or may require other pre-conditions first. +(For example, REP sockets cannot normally send data until they have first received a request, +while SUB sockets can only receive data and never send it.)

+
+

nng_ctx_sendmsg

+

The nng_ctx_sendmsg function sends the msg over the context ctx.

+

If this function returns zero, then the socket will dispose of msg when the transmission is complete. +If the function returns a non-zero status, then the call retains the responsibility for disposing of msg.

+

The flags can contain the value NNG_FLAG_NONBLOCK, indicating that the function should not wait if the socket +cannot accept more data for sending. In such a case, it will return NNG_EAGAIN.

+

nng_ctx_send

+

The nng_ctx_send function sends a message asynchronously, using the nng_aio aio, over the context ctx. +The message to send must have been set on aio using the nng_aio_set_msg function.

+

If the operation completes successfully, then the context will have disposed of the message. +However, if it fails, then callback of aio should arrange for a final disposition of the message. +(The message can be retrieved from aio with nng_aio_get_msg.)

+

Note that callback associated with aio may be called before the message is finally delivered to the recipient. +For example, the message may be sitting in queue, or located in TCP buffers, or even in flight.

+
+

+ + tip +

+

This is the preferred function to use for sending data on a context. While it does require a few extra +steps on the part of the application, the lowest latencies and highest performance will be achieved by using +this function instead of nng_ctx_sendmsg.

+
+

Receiving Messages

+
int nng_ctx_recvmsg(nng_ctx ctx, nng_msg **msgp, int flags);
+void nng_ctx_recv(nng_ctx ctx, nng_aio *aio);
+
+

These functions (, nng_ctx_recvmsg and nng_ctx_recv) receive +messages over the context ctx. The differences in their behaviors are as follows.

+
+

+ + note +

+

The semantics of what receving a message means varies from protocol to +protocol, so examination of the protocol documentation is encouraged. +Additionally, some protocols may not support receiving at all or may require other pre-conditions first. +(For example, REQ sockets cannot normally receive data until they have first sent a request.)

+
+

nng_recvmsg

+

The nng_ctx_recvmsg function receives a message and stores a pointer to the nng_msg for that message in msgp.

+

The flags can contain the value NNG_FLAG_NONBLOCK, indicating that the function should not wait if the socket +has no messages available to receive. In such a case, it will return NNG_EAGAIN.

+

nng_recv_aio

+

The nng_ctx_send function receives a message asynchronously, using the nng_aio aio, over the context ctx. +On success, the received message can be retrieved from the aio using the nng_aio_get_msg function.

+
+

+ + note +

+

It is important that the application retrieves the message, and disposes of it accordingly. +Failure to do so will leak the memory.

+
+
+

+ + tip +

+

This is the preferred function to use for receiving data on a context. While it does require a few extra +steps on the part of the application, the lowest latencies and highest performance will be achieved by using +this function instead of nng_ctx_recvmsg.

+
+

Context Options

+
int nng_ctx_get_bool(nng_ctx ctx, const char *opt, bool *valp);
+int nng_ctx_get_int(nng_ctx ctx, const char *opt, int *valp);
+int nng_ctx_get_ms(nng_ctx ctx, const char *opt, nng_duration *valp);
+int nng_ctx_get_size(nng_ctx ctx, const char *opt, size_t *valp);
+int nng_ctx_get_uint64(nng_ctx ctx, const char *opt, uint64_t *valp);
+
+int nng_ctx_set_bool(nng_ctx ctx, const char *opt, int val);
+int nng_ctx_set_int(nng_ctx ctx, const char *opt, int val);
+int nng_ctx_set_ms(nng_ctx ctx, const char *opt, nng_duration val);
+int nng_ctx_set_size(nng_ctx ctx, const char *opt, size_t val);
+int nng_ctx_set_uint64(nng_ctx ctx, const char *opt, uint64_t val);
+
+

These functions are used to retrieve or change the value of an option named opt from the context ctx. +The nng_ctx_get_ functions retrieve the value, and store it in the location valp references. +The nng_ctx_set_ functions change the value for the ctx, taking it from val.

+

These functions access an option as a specific type. The protocol will have details about which options +are available for contexts, and which type they may be accessed using.

+

Examples

+

These examples show building blocks for a concurrent service based on contexts.

+

Example 1: Context Echo Server

+

The following program fragment demonstrates the use of contexts to implement +a concurrent REP service that simply echos messages back +to the sender.

+
struct echo_context {
+    nng_ctx ctx;
+    nng_aio *aio;
+    enum { INIT, RECV, SEND } state;
+};
+
+void
+echo(void *arg)
+{
+    struct echo_context *ec = arg;
+
+    switch (ec->state) {
+    case INIT:
+        ec->state = RECV;
+        nng_ctx_recv(ec->ctx, ec->aio);
+        return;
+    case RECV:
+        if (nng_aio_result(ec->aio) != 0) {
+            // ... handle error
+        }
+        // We reuse the message on the ec->aio
+        ec->state = SEND;
+        nng_ctx_send(ec->ctx, ec->aio);
+        return;
+    case SEND:
+        if (nng_aio_result(ec->aio) != 0) {
+            // ... handle error
+        }
+        ec->state = RECV;
+        nng_ctx_recv(ec->ctx, ec->aio);
+        return;
+    }
+}
+
+

Example 2: Starting the Echo Service

+

Given the above fragment, the following example shows setting up the service. +It assumes that the socket has already been +created and any transports set up as well with functions such as nng_dial or nng_listen.

+

+#define CONCURRENCY 1024
+
+static struct echo_context ecs[CONCURRENCY];
+
+void
+start_echo_service(nng_socket rep_socket)
+{
+    for (int i = 0; i < CONCURRENCY; i++) {
+        // error checks elided for clarity
+        nng_ctx_open(&ecs[i].ctx, rep_socket);
+        nng_aio_alloc(&ecs[i].aio, echo, ecs+i);
+        ecs[i].state = INIT;
+        echo(ecs+i); // start it running
+    }
+}
+
+ + + + + + +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + +
+ + diff --git a/ref/api/index.html b/ref/api/index.html index db3f30c3..5372ced4 100644 --- a/ref/api/index.html +++ b/ref/api/index.html @@ -233,6 +233,7 @@ include the nng/nng.h header file like so:

  • Initialization
  • Messages
  • Sockets
  • +
  • Contexts
  • Memory
  • Time
  • URLs
  • diff --git a/ref/api/memory.html b/ref/api/memory.html index 32319564..ddacea19 100644 --- a/ref/api/memory.html +++ b/ref/api/memory.html @@ -278,7 +278,7 @@ can be used to deallocate strings allocated with - @@ -292,7 +292,7 @@ can be used to deallocate strings allocated with - diff --git a/ref/api/sock.html b/ref/api/sock.html index 215726e0..cdb4b824 100644 --- a/ref/api/sock.html +++ b/ref/api/sock.html @@ -485,7 +485,7 @@ Failure to do so will leak the memory.

    This is the preferred function to use for receiving data on a socket. While it does require a few extra steps on the part of the application, the lowest latencies and highest performance will be achieved by using -this function instead of nng_recv or nng_recvmsg.

    +this function instead of nng_recv or nng_recvmsg.

    Polling Socket Events

    int nng_socket_get_recv_poll_fd(nng_socket s, int *fdp);
    @@ -586,7 +586,7 @@ int main(int argc, char **argv) {
     }
     

    Example 3: Watching a Periodic Timestamp

    -

    This example demonstrates the use of nng_aio, [nng_recv_aio], to build a client to +

    This example demonstrates the use of nng_aio, nng_recv_aio, to build a client to watch for messages received from the service created in Example 2. Error handling is elided for the sake of clarity.

    #include <stdlib.h>
    @@ -645,7 +645,7 @@ int main(int argc, char **argv) {
                                     
                                 
     
    -                            
     
    @@ -659,7 +659,7 @@ int main(int argc, char **argv) {
                             
                         
     
    -                    
                 
    -- 
    cgit v1.2.3-70-g09d2