Skip to content

Commit 5af28d2

Browse files
committed
[fpmsyncd] support flush with a timer
1 parent 90fcead commit 5af28d2

3 files changed

Lines changed: 62 additions & 5 deletions

File tree

fpmsyncd/fpmsyncd.cpp

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,35 @@
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

1617
using namespace std;
1718
using 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+
}

fpmsyncd/fpmsyncd.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#ifndef __FPMSYNCD__
2+
#define __FPMSYNCD__
3+
4+
// redispipeline has a maximum capacity of 50000 entries
5+
#define ROUTE_SYNC_PPL_SIZE 50000
6+
7+
#endif

fpmsyncd/routesync.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ static decltype(auto) makeNlAddr(const T& ip)
7676

7777

7878
RouteSync::RouteSync(RedisPipeline *pipeline) :
79-
m_routeTable(pipeline, APP_ROUTE_TABLE_NAME, true),
79+
m_routeTable(pipeline, APP_ROUTE_TABLE_NAME, true, true),
8080
m_label_routeTable(pipeline, APP_LABEL_ROUTE_TABLE_NAME, true),
8181
m_vnet_routeTable(pipeline, APP_VNET_RT_TABLE_NAME, true),
8282
m_vnet_tunnelTable(pipeline, APP_VNET_RT_TUNNEL_TABLE_NAME, true),

0 commit comments

Comments
 (0)