Skip to content

Commit 63db87a

Browse files
partial compile
1 parent d130b84 commit 63db87a

File tree

7 files changed

+214
-106
lines changed

7 files changed

+214
-106
lines changed

common/Makefile.am

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ endif
2929

3030
libswsscommon_la_SOURCES = \
3131
events_common.cpp \
32+
events_service.cpp \
33+
events.cpp \
3234
logger.cpp \
3335
redisreply.cpp \
3436
configdb.cpp \

common/events.cpp

+48-20
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,32 @@
11
#include "events_pi.h"
22

3+
/*
4+
* Publisher use echo service and subscriber uses cache service
5+
* The eventd process runs this service, which could be down
6+
* All service interactions being async, a timeout is required
7+
* not to block forever on read.
8+
*
9+
* The unit is in milliseconds (in sync with ZMQ_RCVTIMEO of
10+
* zmq_setsockopt.
11+
*/
12+
13+
#define EVENTS_SERVICE_TIMEOUT_MILLISECS 200
14+
315
/*
416
* Track created publishers to avoid duplicates
517
* As we track missed event count by publishing instances, avoiding
618
* duplicates helps reduce load.
719
*/
20+
821
typedef map <string, EventPublisher> lst_publishers_t;
922
lst_publishers_t s_publishers;
1023

11-
EventPublisher::EventPublisher(const string source) :
24+
EventPublisher::EventPublisher() :
1225
m_zmq_ctx(NULL), m_socket(NULL), m_sequence(0), m_init(false)
1326
{
1427
}
1528

16-
int EventPublisher::init(const string event_source, int block_ms)
29+
int EventPublisher::init(const string event_source)
1730
{
1831
m_zmq_ctx = zmq_ctx_new();
1932
m_socket = zmq_socket (m_zmq_ctx, ZMQ_PUB);
@@ -26,7 +39,11 @@ int EventPublisher::init(const string event_source, int block_ms)
2639
// Any message published before connection establishment is dropped.
2740
//
2841
event_service m_event_svc;
29-
rc = m_event_svc.init_client(block_ms);
42+
/*
43+
* Event service could be down. So have a timeout.
44+
*
45+
*/
46+
rc = m_event_svc.init_client(m_zmq_ctx, EVENTS_SERVICE_TIMEOUT_MILLISECS);
3047
RET_ON_ERR (rc == 0, "Failed to init event service");
3148

3249
rc = m_event_svc.echo_send("hello");
@@ -57,7 +74,7 @@ EventPublisher::event_publish(const string tag, const event_params_t *params)
5774
string s;
5875

5976
/* Failure is no-op; The eventd service my be down
60-
* NOTE: This call atmost blocks for block_ms milliseconds
77+
* NOTE: This call atmost blocks for EVENTS_SERVICE_TIMEOUT_MILLISECS
6178
* as provided in publisher init.
6279
*/
6380
m_event_service.echo_receive(s);
@@ -82,11 +99,11 @@ EventPublisher::event_publish(const string tag, const event_params_t *params)
8299
event_data[EVENT_RUNTIME_ID] = m_runtime_id;
83100
event_data[EVENT_SEQUENCE] = seq_to_str(m_sequence);
84101

85-
return zmq_message_send(m_event_source, event_data);
102+
return zmq_message_send(m_socket, m_event_source, event_data);
86103
}
87104

88105
event_handle_t
89-
events_init_publisher(const string event_source, int block_millisecs)
106+
events_init_publisher(const string event_source)
90107
{
91108
event_handle_t ret = NULL;
92109
lst_publishers_t::iterator it = s_publishers.find(event_source);
@@ -97,7 +114,7 @@ events_init_publisher(const string event_source, int block_millisecs)
97114
else {
98115
EventPublisher *p = new EventPublisher();
99116

100-
int rc = p->init(event_source, block_millisecs);
117+
int rc = p->init(event_source);
101118

102119
if (rc != 0) {
103120
delete p;
@@ -132,10 +149,10 @@ event_publish(event_handle_t handle, const string tag, const event_params_t *par
132149
{
133150
for(it=s_publishers.begin(); it != s_publishers.end(); ++it) {
134151
if (it->second == handle) {
135-
it->second->event_publish(tag, params);
136-
break;
152+
return it->second->event_publish(tag, params);
137153
}
138154
}
155+
return -1;
139156
}
140157

141158

@@ -179,7 +196,9 @@ EventSubscriber::~EventSubscriber()
179196
break;
180197
}
181198
events.push_back(evt_str);
182-
if(chrono::steady_clock::now() - start > chrono::seconds(2))
199+
chrono::steady_clock::timepoint now = chrono::steady_clock::now();
200+
if (chrono::duration_cast<std::chrono::milliseconds>(now - start) >
201+
CACHE_DRAIN_IN_MILLISECS)
183202
break;
184203
}
185204

@@ -223,12 +242,9 @@ EventSubscriber::init(bool use_cache, const event_subscribe_sources_t *subs_sour
223242
}
224243

225244
if (use_cache) {
226-
rc = m_event_svc.init_client(m_zmq_ctx);
245+
rc = m_event_svc.init_client(m_zmq_ctx, EVENTS_SERVICE_TIMEOUT_MILLISECS);
227246
RET_ON_ERR(rc == 0, "Fails to init the service");
228247

229-
/* Shadow the cache SUBS connect request, as it is async */
230-
m_event_svc.send_recv(EVENT_ECHO);
231-
232248
if (m_event_svc.cache_stop() == 0) {
233249
// Stopped an active cache
234250
m_cache_read = true;
@@ -261,10 +277,12 @@ EventSubscriber::prune_track()
261277

262278

263279
int
264-
EventSubscriber::event_receive(event_str_t &event, int &missed_cnt)
280+
EventSubscriber::event_receive(string &&key, event_params_t &params, int &missed_cnt)
265281
{
266-
event.clear();
267-
while (event.empty()) {
282+
key.clear();
283+
event_params_t().swap(params);
284+
285+
while (key.empty()) {
268286
internal_event_t event_data;
269287
int rc = 0;
270288

@@ -303,7 +321,16 @@ EventSubscriber::event_receive(event_str_t &event, int &missed_cnt)
303321
}
304322
}
305323
if (missed_cnt >= 0) {
306-
event = event_data[EVENT_STR_DATA];
324+
map_str_str_t ev;
325+
326+
deserialize(event_data[EVENT_STR_DATA], ev);
327+
RET_ON_ERR(ev.size() == 1, "Expect string (%s) deserialize to one key",
328+
event_data[EVENT_STR_DATA].c_str());
329+
330+
key = ev.begin()->first;
331+
332+
deserialize(ev.begin()->second, params);
333+
307334
}
308335
}
309336
out:
@@ -345,10 +372,11 @@ events_deinit_subscriber(event_handle_t &handle)
345372

346373

347374
int
348-
event_receive(event_handle_t handle, event_str_t &event, int &missed_cnt)
375+
event_receive(event_handle_t handle, string &key,
376+
event_params_t &params, int &missed_cnt)
349377
{
350378
if ((handle == s_subscriber) && (s_subscriber != NULL)) {
351-
return s_subscriber->event_receive(event, missed_cnt);
379+
return s_subscriber->event_receive(key, params, missed_cnt);
352380
}
353381
return -1;
354382
}

common/events.h

+50-25
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#ifndef _EVENTS_H
2+
#define _EVENTS_H
3+
14
/*
25
* Events library
36
*
@@ -30,20 +33,12 @@ typedef void* event_handle_t;
3033
* returned by this call is tagged with this source, transparently. The receiver
3134
* could subscribe with this source as filter.
3235
*
33-
* block_millisecs -
34-
* Block either until publisher connects successfully or timeout
35-
* whichever earlier.
36-
* 0 - No blocling.
37-
* -1 - Block until connected.
38-
* N - Count in milli seconds to wait.
39-
* NOTE: The connection is to eventd service, which could be down.
4036
* Return
4137
* Non NULL handle
4238
* NULL on failure
4339
*/
4440

45-
event_handle_t events_init_publisher(std::string event_source,
46-
int block_millisecs);
41+
event_handle_t events_init_publisher(std::string event_source);
4742

4843
/*
4944
* De-init/free the publisher
@@ -65,7 +60,7 @@ typedef std::map<std::string, std::string> event_params_t;
6560
/*
6661
* timestamp param name
6762
*/
68-
const string event_ts("timestamp");
63+
const std::string event_ts("timestamp");
6964

7065
/*
7166
* Publish an event
@@ -78,7 +73,7 @@ const string event_ts("timestamp");
7873
* the running instance of a publisher and other a running sequence
7974
* starting from 0, which is local to this runtime-id.
8075
*
81-
* The receiver API keep next last received number for each runtime id
76+
* The receiver API keep last received number for each runtime id
8277
* and use this info to compute missed event count upon next event.
8378
*
8479
* input:
@@ -97,8 +92,11 @@ const string event_ts("timestamp");
9792
* The timestamp should be per rfc3339
9893
* e.g. "2022-08-17T02:39:21.286611Z"
9994
*
95+
* return:
96+
* 0 - On success
97+
* -1 - On failure.
10098
*/
101-
void event_publish(event_handle_t handle, const std::string event_tag,
99+
int event_publish(event_handle_t handle, const std::string event_tag,
102100
const event_params_t *params=NULL);
103101

104102

@@ -112,8 +110,8 @@ typedef std::vector<std::string> event_subscribe_sources_t;
112110
* Input:
113111
* use_cache
114112
* When set to true, it will make use of the cache service transparently.
115-
* The cache service caches events during session down time (last deinit to this
116-
* init call).
113+
* The cache service caches events during session down time. The deinit
114+
* start the caching and init call stops the caching.
117115
*
118116
* lst_subscribe_sources_t
119117
* List of subscription sources of interest.
@@ -138,26 +136,37 @@ event_handle_t events_init_subscriber(bool use_cache=false,
138136
*/
139137
void events_deinit_subscriber(event_handle_t &handle);
140138

141-
/*
142-
* Received event as JSON string as
143-
* < YANG path of schema >: {
144-
* event_params_t
145-
* }
146-
*/
147-
typedef std::string event_str_t;
148-
149139
/*
150140
* Receive an event.
151141
* A blocking call.
152142
*
153143
* This API maintains an expected sequence number and use the received
154-
* sequence in event to compute missed events count.
144+
* sequence in event to compute missed events count. The missed count
145+
* set of events missed from this sender.
146+
*
147+
* Received event:
148+
* It is a form of JSON struct, with a single key and
149+
* params as value. The key is <YANG schema module name>:<YANG schema tag
150+
* name> and params is as per schema description for that event.
151+
*
152+
* e.g.
153+
* { "sonic-events-bgp:bgp-state": {
154+
* "ip": "100.126.188.90",
155+
* "status": "down",
156+
* "timestamp": "2022-08-17T02:39:21.286611Z"
157+
* }
158+
* }
155159
*
156160
* input:
157161
* handle - As obtained from events_init_subscriber
158162
*
159163
* output:
160-
* event - Received event.
164+
* key :
165+
* YANG path as <event source module name>:<event tag/container name
166+
* within the module that describes the event>
167+
*
168+
* params:
169+
* Parms associated.
161170
*
162171
* missed_cnt:
163172
* Count of missed events from this sender, before this event. Sum of
@@ -168,5 +177,21 @@ typedef std::string event_str_t;
168177
* -1 - On failure. The handle is not valid.
169178
*
170179
*/
171-
int event_receive(event_handle_t handle, event_str_t &event, int &missed_cnt);
180+
int event_receive(event_handle_t handle, std::string &key,
181+
event_params_t &params, int &missed_cnt);
182+
183+
184+
/*
185+
* Cache drain timeout.
186+
*
187+
* When de-init is called, it calls stop cache service.
188+
* But before this point, there could be events received in zmq's
189+
* local cache pending read and those that arrived since last read.
190+
* These events will not be seen by cache service.
191+
* So read those off and give it to cache service as starting stock.
192+
* As we don't have a clue on count in zmq's cache, read in non-block
193+
* mode for a period.
194+
*/
195+
#define CACHE_DRAIN_IN_MILLISECS 1000
172196

197+
#endif /* !_EVENTS_H */

0 commit comments

Comments
 (0)