Skip to content

Conversation

@mikecdavis
Copy link
Contributor

Summary

  • Allow OptimizelyFactory to accept a plain old context object (POCO)
  • Rework ExecutionCtx into ExecGroup (ala errgroup)
  • Refactor Start methods to NOT manage their own goroutines, but assume to be executed within one (this is similar to http.ListenAndServe)

This refactor started when I wanted to manage the OptimizelyClient lifecycle in my application, but was surprised that I couldn't easily just pass in my own cancellable context. Instead I had to implement my own ExecutableCtx, which also had concepts I didn't feel were immediately relevant to what I was trying to accomplish. Digging further I saw how the ExecutableCtx was being used it followed more of the semantics of an errgroup which means simply managing a "group" of goroutines.

An added side effect of this change is that ExecGroup is isolated to the client pkg and it's not leaked into the other implementations. Everything now just has to deal with context and overriding the default context feels much more idiomatic.

Copy link
Contributor

@mikeproeng37 mikeproeng37 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm. I am a fan of not exposing a custom construct to help achieve the same thing.

// Initialize the default services with the execution context
if pollingConfigManager, ok := appClient.ConfigManager.(*config.PollingProjectConfigManager); ok {
pollingConfigManager.Start(appClient.executionCtx)
eg.Go(pollingConfigManager.Start)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like how we invert the relationship here

Copy link
Contributor

@mjc1283 mjc1283 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, it makes sense to me 👍


p.startTicker(exeCtx)
p.startTicker(ctx)
pLogger.Debug("Batch event processor started")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With these changes, does this message actually only get logged when the processor is stopped? Since startTicker was changed to return only when the context signals done.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, I'll move the log line.

if p.EventDispatcher == nil {
p.EventDispatcher = NewQueueEventDispatcher(exeCtx.GetContext())
dispatcher := NewQueueEventDispatcher()
defer dispatcher.flushEvents()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this flushEvents necessary? flushEvents is called in startTicker when the context signals done.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are aggressively calling flushEvents() that's true. This particular change is to replace the defer in the QueueEventDispatcher "constructor". https://github.com/optimizely/go-sdk/pull/212/files#diff-663642fbf6b03877a468459e9e872cb5L142-L150

wg.Done()
})

cancel()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cool, we were missing that in the ExecutionContext implementation. The only awkward thing will happen when a user will define cancelable context and cancels with the client:

ctx, _ := context.WithCancel(context.Background())
client.Close()

that will return :

the cancel function returned by context.WithCancel should be called, not discarded, to avoid a context leak

Copy link
Contributor

@pawels-optimizely pawels-optimizely left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good implementation of cancelable context.

@mikecdavis mikecdavis changed the title [DISCUSS] Refactor ExecutionCtx into ExecGroup. Refactor ExecutionCtx into ExecGroup. Dec 10, 2019
@mikecdavis mikecdavis removed the wip label Dec 10, 2019
@mikecdavis mikecdavis force-pushed the mikecdavis/OASIS-5660-context-refact branch from d245a2f to e454957 Compare December 10, 2019 18:27
@mikecdavis mikecdavis force-pushed the mikecdavis/OASIS-5660-context-refact branch from e454957 to 027b174 Compare December 11, 2019 04:24
@mikecdavis mikecdavis merged commit 5477d16 into master Dec 11, 2019
@mikecdavis mikecdavis deleted the mikecdavis/OASIS-5660-context-refact branch December 11, 2019 04:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants