1+ #include < unistd.h>
12#include < string>
23#include < deque>
34#include < limits>
@@ -20,6 +21,7 @@ ZmqServer::ZmqServer(const std::string& endpoint, const std::string& vrf)
2021 : m_endpoint(endpoint),
2122 m_vrf (vrf)
2223{
24+ connect ();
2325 m_buffer.resize (MQ_RESPONSE_MAX_COUNT);
2426 m_runThread = true ;
2527 m_mqPollThread = std::make_shared<std::thread>(&ZmqServer::mqPollThread, this );
@@ -31,6 +33,33 @@ ZmqServer::~ZmqServer()
3133{
3234 m_runThread = false ;
3335 m_mqPollThread->join ();
36+
37+ zmq_close (m_socket);
38+ zmq_ctx_destroy (m_context);
39+ }
40+
41+ void ZmqServer::connect ()
42+ {
43+ SWSS_LOG_ENTER ();
44+ m_context = zmq_ctx_new ();
45+ m_socket = zmq_socket (m_context, ZMQ_PULL);
46+
47+ // Increase recv buffer for use all bandwidth: http://api.zeromq.org/4-2:zmq-setsockopt
48+ int high_watermark = MQ_WATERMARK;
49+ zmq_setsockopt (m_socket, ZMQ_RCVHWM, &high_watermark, sizeof (high_watermark));
50+
51+ if (!m_vrf.empty ())
52+ {
53+ zmq_setsockopt (m_socket, ZMQ_BINDTODEVICE, m_vrf.c_str (), m_vrf.length ());
54+ }
55+
56+ int rc = zmq_bind (m_socket, m_endpoint.c_str ());
57+ if (rc != 0 )
58+ {
59+ SWSS_LOG_THROW (" zmq_bind failed on endpoint: %s, zmqerrno: %d" ,
60+ m_endpoint.c_str (),
61+ zmq_errno ());
62+ }
3463}
3564
3665void ZmqServer::registerMessageHandler (
@@ -90,40 +119,18 @@ void ZmqServer::mqPollThread()
90119 SWSS_LOG_ENTER ();
91120 SWSS_LOG_NOTICE (" mqPollThread begin" );
92121
93- // Producer/Consumer state table are n:1 mapping, so need use PUSH/PULL pattern http://api.zeromq.org/master:zmq-socket
94- void * context = zmq_ctx_new ();;
95- void * socket = zmq_socket (context, ZMQ_PULL);
96-
97- // Increase recv buffer for use all bandwidth: http://api.zeromq.org/4-2:zmq-setsockopt
98- int high_watermark = MQ_WATERMARK;
99- zmq_setsockopt (socket, ZMQ_RCVHWM, &high_watermark, sizeof (high_watermark));
100-
101- if (!m_vrf.empty ())
102- {
103- zmq_setsockopt (socket, ZMQ_BINDTODEVICE, m_vrf.c_str (), m_vrf.length ());
104- }
105-
106- int rc = zmq_bind (socket, m_endpoint.c_str ());
107- if (rc != 0 )
108- {
109- SWSS_LOG_THROW (" zmq_bind failed on endpoint: %s, zmqerrno: %d, message: %s" ,
110- m_endpoint.c_str (),
111- zmq_errno (),
112- strerror (zmq_errno ()));
113- }
114-
115122 // zmq_poll will use less CPU
116123 zmq_pollitem_t poll_item;
117124 poll_item.fd = 0 ;
118- poll_item.socket = socket ;
125+ poll_item.socket = m_socket ;
119126 poll_item.events = ZMQ_POLLIN;
120127 poll_item.revents = 0 ;
121128
122129 SWSS_LOG_NOTICE (" bind to zmq endpoint: %s" , m_endpoint.c_str ());
123130 while (m_runThread)
124131 {
125132 // receive message
126- rc = zmq_poll (&poll_item, 1 , 1000 );
133+ auto rc = zmq_poll (&poll_item, 1 , 1000 );
127134 if (rc == 0 || !(poll_item.revents & ZMQ_POLLIN))
128135 {
129136 // timeout or other event
@@ -132,7 +139,7 @@ void ZmqServer::mqPollThread()
132139 }
133140
134141 // receive message
135- rc = zmq_recv (socket , m_buffer.data (), MQ_RESPONSE_MAX_COUNT, ZMQ_DONTWAIT);
142+ rc = zmq_recv (m_socket , m_buffer.data (), MQ_RESPONSE_MAX_COUNT, ZMQ_DONTWAIT);
136143 if (rc < 0 )
137144 {
138145 int zmq_err = zmq_errno ();
@@ -160,11 +167,14 @@ void ZmqServer::mqPollThread()
160167 // deserialize and write to redis:
161168 handleReceivedData (m_buffer.data (), rc);
162169 }
163-
164- zmq_close (socket);
165- zmq_ctx_destroy (context);
166-
167170 SWSS_LOG_NOTICE (" mqPollThread end" );
168171}
169172
173+ // TODO: To be implemented later, required for ZMQ_CLIENT & ZMQ_SERVER
174+ // socket types in response path.
175+ void ZmqServer::sendMsg (
176+ const std::string &dbName, const std::string &tableName,
177+ const std::vector<swss::KeyOpFieldsValuesTuple> &values) {
178+ return ;
179+ }
170180}
0 commit comments