99#include " subscriberstatetable.h"
1010#include " warmRestartHelper.h"
1111#include " fpmsyncd/fpmlink.h"
12+ #include " fpmsyncd/fpmsyncd.h"
1213#include " fpmsyncd/routesync.h"
1314
1415#include < netlink/route/route.h>
1516
1617using namespace std ;
1718using namespace swss ;
1819
20+ // SELECT_TIMEOUT specifies the maximum wait time in milliseconds (-1 == infinite)
21+ static int SELECT_TIMEOUT ;
22+ #define INFINITE -1
23+ #define FLUSH_TIMEOUT 500 // 500 milliseconds
24+ static int gFlushTimeout = FLUSH_TIMEOUT ;
25+ // consider the traffic is small if pipeline contains < 500 entries
26+ #define SMALL_TRAFFIC 500
27+
28+ /* *
29+ * @brief fpmsyncd invokes redispipeline's flush with a timer
30+ *
31+ * redispipeline would automatically flush itself when full,
32+ * but fpmsyncd can invoke pipeline's flush even if it's not full yet.
33+ *
34+ * By setting SELECT_TIMEOUT, fpmsyncd controls the flush interval.
35+ *
36+ * @param pipeline reference to the pipeline to be flushed
37+ * @param scheduled if true, timer for fpmsyncd flush expired
38+ */
39+ void flushPipeline (RedisPipeline& pipeline, bool scheduled);
40+
1941/*
2042 * Default warm-restart timer interval for routing-stack app. To be used only if
2143 * no explicit value has been defined in configuration.
@@ -61,7 +83,7 @@ int main(int argc, char **argv)
6183 DBConnector applStateDb (" APPL_STATE_DB" , 0 );
6284 std::unique_ptr<NotificationConsumer> routeResponseChannel;
6385
64- RedisPipeline pipeline (&db);
86+ RedisPipeline pipeline (&db, ROUTE_SYNC_PPL_SIZE );
6587 RouteSync sync (&pipeline);
6688
6789 DBConnector stateDb (" STATE_DB" , 0 );
@@ -152,12 +174,14 @@ int main(int argc, char **argv)
152174 sync.m_warmStartHelper .setState (WarmStart::WSDISABLED );
153175 }
154176
177+ SELECT_TIMEOUT = INFINITE ;
178+
155179 while (true )
156180 {
157181 Selectable *temps;
158182
159183 /* Reading FPM messages forever (and calling "readMe" to read them) */
160- s.select (&temps);
184+ auto ret = s.select (&temps, SELECT_TIMEOUT );
161185
162186 /*
163187 * Upon expiration of the warm-restart timer or eoiu Hold Timer, proceed to run the
@@ -286,8 +310,7 @@ int main(int argc, char **argv)
286310 }
287311 else if (!warmStartEnabled || sync.m_warmStartHelper .isReconciled ())
288312 {
289- pipeline.flush ();
290- SWSS_LOG_DEBUG (" Pipeline flushed" );
313+ flushPipeline (pipeline, ret==Select::TIMEOUT );
291314 }
292315 }
293316 }
@@ -304,3 +327,30 @@ int main(int argc, char **argv)
304327
305328 return 1 ;
306329}
330+
331+ void flushPipeline (RedisPipeline& pipeline, bool scheduled) {
332+
333+ size_t remaining = pipeline.size ();
334+
335+ if (remaining == 0 ) {
336+ SELECT_TIMEOUT = INFINITE ;
337+ return ;
338+ }
339+
340+ int idle = pipeline.getIdleTime ();
341+
342+ // flush right away
343+ if (remaining < SMALL_TRAFFIC || idle >= gFlushTimeout || idle <= 0 || scheduled) {
344+
345+ pipeline.flush ();
346+
347+ SELECT_TIMEOUT = INFINITE ;
348+
349+ SWSS_LOG_DEBUG (" Pipeline flushed" );
350+
351+ return ;
352+ }
353+
354+ // postpone the flush
355+ SELECT_TIMEOUT = gFlushTimeout - idle;
356+ }
0 commit comments