-
Notifications
You must be signed in to change notification settings - Fork 25
feat: honor polling interval across process restarts #282
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
08dc14c
99c99a2
a0154a9
117a0cc
70faaa6
85a993a
1aacaf1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -244,30 +244,45 @@ static final class PollingDataSourceBuilderImpl extends PollingDataSourceBuilder | |
implements DiagnosticDescription, DataSourceRequiresFeatureFetcher { | ||
@Override | ||
public DataSource build(ClientContext clientContext) { | ||
clientContext.getDataSourceUpdateSink().setStatus( | ||
clientContext.isInBackground() ? ConnectionInformation.ConnectionMode.BACKGROUND_POLLING : | ||
ClientContextImpl clientContextImpl = ClientContextImpl.get(clientContext); | ||
clientContextImpl.getDataSourceUpdateSink().setStatus( | ||
clientContextImpl.isInBackground() ? ConnectionInformation.ConnectionMode.BACKGROUND_POLLING : | ||
ConnectionInformation.ConnectionMode.POLLING, | ||
null | ||
); | ||
int actualPollIntervalMillis = clientContext.isInBackground() ? backgroundPollIntervalMillis : | ||
|
||
int pollInterval = clientContextImpl.isInBackground() ? backgroundPollIntervalMillis : | ||
pollIntervalMillis; | ||
int initialDelayMillis; | ||
|
||
long initialDelayMillis; | ||
if (clientContext.isInBackground() && Boolean.FALSE.equals(clientContext.getPreviouslyInBackground())) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For reviewers: This background/foregrounding distinction is no more! The only impact foreground/background has is on the polling interval. Now they are treated the same after that which results in some improvements in behavioral consistency. |
||
// If we're transitioning from foreground to background, then we don't want to do a | ||
// poll right away because we already have recent flag data. Start polling *after* | ||
// the first background poll interval. | ||
initialDelayMillis = backgroundPollIntervalMillis; | ||
} else { | ||
// If we're in the foreground-- or, if we're in the background but we started out | ||
// that way rather than transitioning-- then we should do the first poll right away. | ||
initialDelayMillis = 0; | ||
// TODO: refactor context hashing calls to use a common util | ||
String hashed = new ContextHasher().hash(clientContextImpl.getEvaluationContext().getFullyQualifiedKey()); | ||
|
||
long lastUpdated = 0; // assume last updated is beginning of time | ||
for (ContextIndex.IndexEntry entry : clientContextImpl.getPerEnvironmentData().getIndex().data) { | ||
if (entry.contextId.equals(hashed)) { | ||
lastUpdated = entry.timestamp; | ||
} | ||
} | ||
|
||
// To avoid unnecessarily frequent polling requests due to process or application lifecycle, we have added | ||
// this initial delay logic. Calculate how much time has passed since the last update, if that is less than | ||
// the polling interval, delay by the difference, otherwise 0 delay. | ||
long elapsedSinceUpdate = System.currentTimeMillis() - lastUpdated; | ||
initialDelayMillis = Math.max(pollInterval - elapsedSinceUpdate, 0); | ||
} | ||
ClientContextImpl clientContextImpl = ClientContextImpl.get(clientContext); | ||
|
||
return new PollingDataSource( | ||
clientContext.getEvaluationContext(), | ||
clientContext.getDataSourceUpdateSink(), | ||
clientContextImpl.getEvaluationContext(), | ||
clientContextImpl.getDataSourceUpdateSink(), | ||
initialDelayMillis, | ||
actualPollIntervalMillis, | ||
pollInterval, | ||
clientContextImpl.getFetcher(), | ||
clientContextImpl.getPlatformState(), | ||
clientContextImpl.getTaskExecutor(), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -243,6 +243,12 @@ public boolean upsert(@NonNull LDContext context, @NonNull Flag flag) { | |
|
||
String contextId = hashedContextId(context); | ||
environmentStore.setContextData(contextId, updatedFlags); | ||
|
||
if (index == null) { | ||
index = environmentStore.getIndex(); | ||
} | ||
index = index.updateTimestamp(contextId, System.currentTimeMillis()); | ||
environmentStore.setIndex(index); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For reviewers: This code path is hit when a flag patch comes in. |
||
} | ||
|
||
Collection<String> updatedFlag = Collections.singletonList(flag.getKey()); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For reviewers: Updated from using
ClientContext
toClientContextImpl
type here to have access to an internal only object, namely thePerEnvironmentData
.