git subrepo clone (merge) --branch=v3.6.1 https://github.com/nats-io/nats.c.git deps/nats.c
subrepo: subdir: "deps/nats.c" merged: "66cec7f" upstream: origin: "https://github.com/nats-io/nats.c.git" branch: "v3.6.1" commit: "66cec7f" git-subrepo: version: "0.4.6" commit: "b8b46501e"
This commit is contained in:
29
deps/nats.c/examples/stan/CMakeLists.txt
vendored
Normal file
29
deps/nats.c/examples/stan/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
if(NOT NATS_BUILD_EXAMPLES)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# We need this directory to build the examples
|
||||
include_directories(${PROJECT_SOURCE_DIR}/src)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/examples/stan)
|
||||
|
||||
# Get all the .c files in the examples directory
|
||||
file(GLOB EXAMPLES_SOURCES RELATIVE ${PROJECT_SOURCE_DIR}/examples/stan *.c)
|
||||
|
||||
# For each file...
|
||||
foreach(examples_src ${EXAMPLES_SOURCES})
|
||||
|
||||
# Remove the suffix so that it becomes the executable name
|
||||
string(REPLACE ".c" "" examplename ${examples_src})
|
||||
set(exampleexe "stan-${examplename}")
|
||||
|
||||
# Build the executable
|
||||
add_executable(${exampleexe} ${PROJECT_SOURCE_DIR}/examples/stan/${examples_src})
|
||||
|
||||
# Link
|
||||
if(NATS_BUILD_STATIC_EXAMPLES)
|
||||
target_link_libraries(${exampleexe} nats_static ${NATS_EXTRA_LIB})
|
||||
else()
|
||||
target_link_libraries(${exampleexe} nats ${NATS_EXTRA_LIB})
|
||||
endif()
|
||||
|
||||
endforeach()
|
127
deps/nats.c/examples/stan/pub-async.c
vendored
Normal file
127
deps/nats.c/examples/stan/pub-async.c
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
// Copyright 2018 The NATS Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "../examples.h"
|
||||
|
||||
static const char *usage = ""\
|
||||
"-txt text to send (default is 'hello')\n";
|
||||
|
||||
typedef struct __myPubMsgInfo
|
||||
{
|
||||
const char *payload;
|
||||
int size;
|
||||
char ID[30];
|
||||
|
||||
} myPubMsgInfo;
|
||||
|
||||
static volatile bool done = false;
|
||||
|
||||
static void
|
||||
_pubAckHandler(const char *guid, const char *error, void *closure)
|
||||
{
|
||||
myPubMsgInfo *pubMsg = (myPubMsgInfo*) closure;
|
||||
|
||||
printf("Ack handler for message ID=%s Data=%.*s GUID=%s - ",
|
||||
pubMsg->ID, pubMsg->size, pubMsg->payload, guid);
|
||||
|
||||
if (error != NULL)
|
||||
printf("Error= %s\n", error);
|
||||
else
|
||||
printf("Success!\n");
|
||||
|
||||
// This is a good place to free the pubMsg info since
|
||||
// we no longer need it.
|
||||
free(pubMsg);
|
||||
|
||||
// Notify the main thread that we are done. This is
|
||||
// not the proper way and you should use some locking.
|
||||
done = true;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
natsStatus s;
|
||||
stanConnOptions *connOpts = NULL;
|
||||
stanConnection *sc = NULL;
|
||||
myPubMsgInfo *pubMsg = NULL;
|
||||
|
||||
// This example demonstrates the use of the pubAckHandler closure
|
||||
// to correlate published messages and their acks.
|
||||
|
||||
opts = parseArgs(argc, argv, usage);
|
||||
|
||||
printf("Sending 1 message to channel '%s'\n", subj);
|
||||
|
||||
// Now create STAN Connection Options and set the NATS Options.
|
||||
s = stanConnOptions_Create(&connOpts);
|
||||
if (s == NATS_OK)
|
||||
s = stanConnOptions_SetNATSOptions(connOpts, opts);
|
||||
|
||||
// Create the Connection using the STAN Connection Options
|
||||
if (s == NATS_OK)
|
||||
s = stanConnection_Connect(&sc, cluster, clientID, connOpts);
|
||||
|
||||
// Once the connection is created, we can destroy the options
|
||||
natsOptions_Destroy(opts);
|
||||
stanConnOptions_Destroy(connOpts);
|
||||
|
||||
// Create an object that represents our message
|
||||
if (s == NATS_OK)
|
||||
{
|
||||
pubMsg = (myPubMsgInfo*) calloc(1, sizeof(myPubMsgInfo));
|
||||
if (pubMsg == NULL)
|
||||
s = NATS_NO_MEMORY;
|
||||
|
||||
if (s == NATS_OK)
|
||||
{
|
||||
// Say we want to bind the data that we are going to send
|
||||
// to some unique ID that we know about this message.
|
||||
pubMsg->payload = payload;
|
||||
pubMsg->size = (int)strlen(payload);
|
||||
snprintf(pubMsg->ID, sizeof(pubMsg->ID), "%s:%d", "xyz", 234);
|
||||
}
|
||||
}
|
||||
// We send the message and pass our message info as the closure
|
||||
// for the pubAckHandler.
|
||||
if (s == NATS_OK)
|
||||
{
|
||||
s = stanConnection_PublishAsync(sc, subj, pubMsg->payload, pubMsg->size,
|
||||
_pubAckHandler, (void*) pubMsg);
|
||||
|
||||
// Note that if this call fails, then we need to free the pubMsg
|
||||
// object here since it won't be passed to the ack handler.
|
||||
if (s != NATS_OK)
|
||||
free(pubMsg);
|
||||
}
|
||||
|
||||
if (s == NATS_OK)
|
||||
{
|
||||
while (!done)
|
||||
nats_Sleep(15);
|
||||
}
|
||||
|
||||
if (s != NATS_OK)
|
||||
{
|
||||
printf("Error: %d - %s\n", s, natsStatus_GetText(s));
|
||||
nats_PrintLastErrorStack(stderr);
|
||||
}
|
||||
|
||||
// Destroy the connection
|
||||
stanConnection_Destroy(sc);
|
||||
|
||||
// To silence reports of memory still in-use with valgrind.
|
||||
nats_Sleep(50);
|
||||
nats_Close();
|
||||
|
||||
return 0;
|
||||
}
|
143
deps/nats.c/examples/stan/pub.c
vendored
Normal file
143
deps/nats.c/examples/stan/pub.c
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
// Copyright 2018 The NATS Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "../examples.h"
|
||||
|
||||
static const char *usage = ""\
|
||||
"-txt text to send (default is 'hello')\n" \
|
||||
"-count number of messages to send\n" \
|
||||
"-sync publish synchronously (default is async)\n";
|
||||
|
||||
static volatile int ackCount = 0;
|
||||
static volatile int errCount = 0;
|
||||
|
||||
static void
|
||||
_pubAckHandler(const char *guid, const char *error, void *closure)
|
||||
{
|
||||
// This callback can be invoked by different threads for the
|
||||
// same connection, so access should be protected. For this
|
||||
// example, we don't.
|
||||
ackCount++;
|
||||
if (error != NULL)
|
||||
{
|
||||
printf("pub ack for guid:%s error=%s\n", guid, error);
|
||||
errCount++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
connectionLostCB(stanConnection *sc, const char *errTxt, void *closure)
|
||||
{
|
||||
bool *connLost = (bool*) closure;
|
||||
|
||||
printf("Connection lost: %s\n", errTxt);
|
||||
*connLost = true;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
natsStatus s;
|
||||
stanConnOptions *connOpts = NULL;
|
||||
stanConnection *sc = NULL;
|
||||
int len;
|
||||
bool connLost = false;
|
||||
|
||||
opts = parseArgs(argc, argv, usage);
|
||||
len = (int) strlen(payload);
|
||||
|
||||
printf("Sending %" PRId64 " messages to channel '%s'\n", total, subj);
|
||||
|
||||
// Now create STAN Connection Options and set the NATS Options.
|
||||
s = stanConnOptions_Create(&connOpts);
|
||||
if (s == NATS_OK)
|
||||
s = stanConnOptions_SetNATSOptions(connOpts, opts);
|
||||
|
||||
// Set smaller ping intervals
|
||||
if (s == NATS_OK)
|
||||
s = stanConnOptions_SetPings(connOpts, 1, 5);
|
||||
|
||||
// Add a callback to be notified if the STAN connection is lost for good.
|
||||
if (s == NATS_OK)
|
||||
s = stanConnOptions_SetConnectionLostHandler(connOpts, connectionLostCB, (void*)&connLost);
|
||||
|
||||
/*
|
||||
// To reduce MaxPubAcksInflight to 1000 and factor of 1.0
|
||||
if (s == NATS_OK)
|
||||
s = stanConnOptions_SetMaxPubAcksInflight(connOpts, 1000, 1.0);
|
||||
*/
|
||||
|
||||
// Create the Connection using the STAN Connection Options
|
||||
if (s == NATS_OK)
|
||||
s = stanConnection_Connect(&sc, cluster, clientID, connOpts);
|
||||
|
||||
// Once the connection is created, we can destroy the options
|
||||
natsOptions_Destroy(opts);
|
||||
stanConnOptions_Destroy(connOpts);
|
||||
|
||||
if (s == NATS_OK)
|
||||
start = nats_Now();
|
||||
|
||||
for (count = 0; (s == NATS_OK) && (count < total); count++)
|
||||
{
|
||||
if (async)
|
||||
s = stanConnection_PublishAsync(sc, subj, (const void*) payload, len, _pubAckHandler, NULL);
|
||||
else
|
||||
s = stanConnection_Publish(sc, subj, (const void*) payload, len);
|
||||
}
|
||||
|
||||
if (!connLost && (s == NATS_OK))
|
||||
{
|
||||
if (async)
|
||||
{
|
||||
while (ackCount != total)
|
||||
nats_Sleep(15);
|
||||
}
|
||||
|
||||
printPerf("Sent");
|
||||
printf("Publish ack received: %d - with error: %d\n", ackCount, errCount);
|
||||
}
|
||||
|
||||
// If the connection was created, try to close it
|
||||
if (!connLost && (sc != NULL))
|
||||
{
|
||||
natsStatus closeSts = stanConnection_Close(sc);
|
||||
|
||||
if ((s == NATS_OK) && (closeSts != NATS_OK))
|
||||
s = closeSts;
|
||||
}
|
||||
|
||||
if (s != NATS_OK)
|
||||
{
|
||||
// If we finished before the end, let's wait a tiny
|
||||
// bit to see if the failure is due to connection lost.
|
||||
if (ackCount != total)
|
||||
nats_Sleep(100);
|
||||
|
||||
// If connection was lost, the real reason is reported
|
||||
// the the connectionLostCB callback.
|
||||
if (!connLost)
|
||||
{
|
||||
printf("Error: %d - %s\n", s, natsStatus_GetText(s));
|
||||
nats_PrintLastErrorStack(stderr);
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy the connection
|
||||
stanConnection_Destroy(sc);
|
||||
|
||||
// To silence reports of memory still in-use with valgrind.
|
||||
nats_Sleep(50);
|
||||
nats_Close();
|
||||
|
||||
return 0;
|
||||
}
|
235
deps/nats.c/examples/stan/sub.c
vendored
Normal file
235
deps/nats.c/examples/stan/sub.c
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
// Copyright 2018 The NATS Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "../examples.h"
|
||||
|
||||
static const char *usage = ""\
|
||||
"-c cluster name (default \"test-cluster\")\n" \
|
||||
"-id client ID (default \"client\"\n" \
|
||||
"-count number of messages to receive\n" \
|
||||
"-last deliver starting with last published message (default)\n" \
|
||||
"-all deliver all available messages\n" \
|
||||
"-seq deliver starting at given sequence number\n" \
|
||||
"-durable durable subscription name\n" \
|
||||
"-qgroup queue group name\n" \
|
||||
"-unsubscribe unsubscribe the durable on exit\n";
|
||||
|
||||
static volatile bool done = false;
|
||||
|
||||
static void
|
||||
onMsg(stanConnection *sc, stanSubscription *sub, const char *channel, stanMsg *msg, void *closure)
|
||||
{
|
||||
if (print)
|
||||
printf("Received on [%s]: sequence:%" PRIu64 " data:%.*s timestamp:%" PRId64 " redelivered: %s\n",
|
||||
channel,
|
||||
stanMsg_GetSequence(msg),
|
||||
stanMsg_GetDataLength(msg),
|
||||
stanMsg_GetData(msg),
|
||||
stanMsg_GetTimestamp(msg),
|
||||
stanMsg_IsRedelivered(msg) ? "yes" : "no");
|
||||
|
||||
if (start == 0)
|
||||
start = nats_Now();
|
||||
|
||||
// We should be using a mutex to protect those variables since
|
||||
// they are used from the subscription's delivery and the main
|
||||
// threads. For demo purposes, this is fine.
|
||||
if (count == total-1)
|
||||
{
|
||||
natsStatus s;
|
||||
|
||||
elapsed = nats_Now() - start;
|
||||
|
||||
if (unsubscribe)
|
||||
s = stanSubscription_Unsubscribe(sub);
|
||||
else
|
||||
s = stanSubscription_Close(sub);
|
||||
|
||||
if (s != NATS_OK)
|
||||
{
|
||||
printf("Error: %d - %s\n", s, natsStatus_GetText(s));
|
||||
nats_PrintLastErrorStack(stderr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// If manual acknowledgment was selected, we would acknowledge
|
||||
// the message this way:
|
||||
stanSubscription_AckMsg(sub, msg);
|
||||
*/
|
||||
|
||||
stanMsg_Destroy(msg);
|
||||
|
||||
// Increment only here so that when the main thread detects
|
||||
// that the total has been sent, it does not start cleaning
|
||||
// objects before we have closed the subscription and destroyed
|
||||
// the last message. This is to reduce risk of valgrind reporting
|
||||
// memory still in-use.
|
||||
count++;
|
||||
}
|
||||
|
||||
#if WIN32
|
||||
static BOOL
|
||||
sigHandler(DWORD fdwCtrlType)
|
||||
{
|
||||
if (fdwCtrlType==CTRL_C_EVENT)
|
||||
{
|
||||
done = true;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
#else
|
||||
static void
|
||||
sigHandler(int ignored) {
|
||||
done = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
connectionLostCB(stanConnection *sc, const char *errTxt, void *closure)
|
||||
{
|
||||
bool *connLost = (bool*) closure;
|
||||
|
||||
printf("Connection lost: %s\n", errTxt);
|
||||
*connLost = true;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
natsStatus s;
|
||||
stanConnOptions *connOpts = NULL;
|
||||
stanSubOptions *subOpts = NULL;
|
||||
stanConnection *sc = NULL;
|
||||
stanSubscription *sub = NULL;
|
||||
bool connLost = false;
|
||||
|
||||
opts = parseArgs(argc, argv, usage);
|
||||
|
||||
printf("Receiving %" PRId64 " messages from channel '%s'\n", total, subj);
|
||||
|
||||
// Now create STAN Connection Options and set the NATS Options.
|
||||
s = stanConnOptions_Create(&connOpts);
|
||||
if (s == NATS_OK)
|
||||
s = stanConnOptions_SetNATSOptions(connOpts, opts);
|
||||
|
||||
// Add a callback to be notified if the STAN connection is lost for good.
|
||||
if (s == NATS_OK)
|
||||
s = stanConnOptions_SetConnectionLostHandler(connOpts, connectionLostCB, (void*)&connLost);
|
||||
|
||||
// Create the Connection using the STAN Connection Options
|
||||
if (s == NATS_OK)
|
||||
s = stanConnection_Connect(&sc, cluster, clientID, connOpts);
|
||||
|
||||
// Once connection is created, we can destroy opts and connOpts
|
||||
natsOptions_Destroy(opts);
|
||||
stanConnOptions_Destroy(connOpts);
|
||||
|
||||
if (s == NATS_OK)
|
||||
s = stanSubOptions_Create(&subOpts);
|
||||
|
||||
// If durable
|
||||
if ((s == NATS_OK) && (durable != NULL))
|
||||
s = stanSubOptions_SetDurableName(subOpts, durable);
|
||||
|
||||
// Set position
|
||||
if (s == NATS_OK)
|
||||
{
|
||||
if (deliverAll)
|
||||
s = stanSubOptions_DeliverAllAvailable(subOpts);
|
||||
else if (deliverLast)
|
||||
s = stanSubOptions_StartWithLastReceived(subOpts);
|
||||
else if (deliverSeq > 0)
|
||||
s = stanSubOptions_StartAtSequence(subOpts, deliverSeq);
|
||||
}
|
||||
|
||||
/*
|
||||
// To manually acknowledge the messages, you would need to set this option
|
||||
if (s == NATS_OK)
|
||||
s = stanSubOptions_SetManualAckMode(subOpts, true);
|
||||
|
||||
// To change the number of MaxInflight messages, set this option.
|
||||
// For instance, to receive a single message between each ACK, set
|
||||
// the value to 1.
|
||||
if (s == NATS_OK)
|
||||
s = stanSubOptions_SetMaxInflight(subOpts, 1);
|
||||
|
||||
// To change the duration after which the server resends unacknowledged
|
||||
// messages, use this option. For instance, cause re-delivery after 5 seconds:
|
||||
if (s == NATS_OK)
|
||||
s = stanSubOptions_SetAckWait(subOpts, 5000);
|
||||
*/
|
||||
|
||||
// Create subscription
|
||||
if (s == NATS_OK)
|
||||
{
|
||||
if (qgroup != NULL)
|
||||
s = stanConnection_QueueSubscribe(&sub, sc, subj, qgroup, onMsg, NULL, subOpts);
|
||||
else
|
||||
s = stanConnection_Subscribe(&sub, sc, subj, onMsg, NULL, subOpts);
|
||||
}
|
||||
|
||||
// Once subscription is created, we can destroy the subOpts object
|
||||
stanSubOptions_Destroy(subOpts);
|
||||
|
||||
if (s == NATS_OK)
|
||||
{
|
||||
#if WIN32
|
||||
SetConsoleCtrlHandler((PHANDLER_ROUTINE) sigHandler, TRUE);
|
||||
#else
|
||||
signal(SIGINT, sigHandler);
|
||||
#endif
|
||||
|
||||
while (!done && !connLost && (count < total))
|
||||
nats_Sleep(15);
|
||||
|
||||
if (!connLost)
|
||||
printPerf("Received");
|
||||
}
|
||||
|
||||
// If test was interrupted before receiving all expected messages,
|
||||
// close or unsubscribe. Otherwise, this is done in the message
|
||||
// callback.
|
||||
if (!connLost && ((sub != NULL) && (count < total)))
|
||||
{
|
||||
if (unsubscribe)
|
||||
s = stanSubscription_Unsubscribe(sub);
|
||||
else
|
||||
s = stanSubscription_Close(sub);
|
||||
}
|
||||
|
||||
// If the connection was created, try to close it
|
||||
if (!connLost && (sc != NULL))
|
||||
{
|
||||
natsStatus closeSts = stanConnection_Close(sc);
|
||||
|
||||
if ((s == NATS_OK) && (closeSts != NATS_OK))
|
||||
s = closeSts;
|
||||
}
|
||||
|
||||
if (s != NATS_OK)
|
||||
{
|
||||
printf("Error: %d - %s\n", s, natsStatus_GetText(s));
|
||||
nats_PrintLastErrorStack(stderr);
|
||||
}
|
||||
|
||||
// Destroy our objects
|
||||
stanSubscription_Destroy(sub);
|
||||
stanConnection_Destroy(sc);
|
||||
|
||||
// To silence reports of memory still in-use with valgrind.
|
||||
nats_Sleep(50);
|
||||
nats_Close();
|
||||
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user