Skip to content
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

Add Geography support to RouterService #17902

Merged
merged 4 commits into from
Oct 20, 2022
Merged

Conversation

pmossman
Copy link
Contributor

@pmossman pmossman commented Oct 12, 2022

What

RouterService selects a task queue based on a connection's Geography stored in the config database, rather than using environment variables.

How

  • Add a GeographyMapper interface that maps Geography enum values to String task queue names
  • Add a 'DefaultGeographyMapper' implementation that OSS will use. Idea here is that Cloud will provide it's own implementation with a '@primary' annotation so that Micronaut favors it over the default implementation.

Reading Order

  • Read my comments top to bottom as an initial guideline

@github-actions github-actions bot added area/platform issues related to the platform area/worker Related to worker labels Oct 12, 2022
@pmossman pmossman temporarily deployed to more-secrets October 12, 2022 19:22 Inactive
@pmossman pmossman temporarily deployed to more-secrets October 12, 2022 20:47 Inactive
@pmossman pmossman temporarily deployed to more-secrets October 13, 2022 00:08 Inactive
@pmossman pmossman temporarily deployed to more-secrets October 13, 2022 18:00 Inactive
@pmossman pmossman requested a review from davinchia October 13, 2022 22:48
@davinchia
Copy link
Contributor

@pmossman is this ready for review?

@pmossman pmossman marked this pull request as ready for review October 14, 2022 01:03
@pmossman
Copy link
Contributor Author

@davinchia yeah I think so!

@pmossman pmossman force-pushed the parker/router-service-using-db branch from 9bfe03b to 8cc89fb Compare October 18, 2022 20:18
@pmossman pmossman temporarily deployed to more-secrets October 18, 2022 20:21 Inactive
@pmossman pmossman force-pushed the parker/router-service-using-db branch 2 times, most recently from f021777 to 9fed5f0 Compare October 19, 2022 00:09
@pmossman pmossman temporarily deployed to more-secrets October 19, 2022 00:11 Inactive
@pmossman pmossman temporarily deployed to more-secrets October 19, 2022 00:24 Inactive
* Copyright (c) 2022 Airbyte, Inc., all rights reserved.
*/

package io.airbyte.commons.temporal.scheduling;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This interface is in the airbyte-commons-temporal module, so that on the Cloud side, the new cloud-workers module can depend on airbyte-commons-temporal without needing a dependency on airbyte-workers.

I debated putting this interface in airbyte-commons-worker but based on the contents of the two modules, airbyte-commons-temporal seemed like a slightly better fit. Definitely open to other opinions here!

@@ -0,0 +1,37 @@
/*
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This diff shows up as a brand new file because I moved the RouterService from /sync/ to /scheduling/` because it's used by the ConnectionManagerWorkflow, not the SyncWorkflow.

This diff also contains the new functionality of reading the connection's Geography from the database instead of from the environment variable


return new RouteToSyncTaskQueueOutput(taskQueueForConnectionId);
return new RouteToSyncTaskQueueOutput(taskQueueForConnectionId);
} catch (final IOException e) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now that the routerService queries the database, an IOException is possible. Throw a RetryableException if encountered

Copy link
Contributor

Choose a reason for hiding this comment

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

Remind me again, where do we catch the RetryableException? I can't look since as my IntelliJ is pooping out on me.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Asked here: https://airbytehq-team.slack.com/archives/C03AS1GAQV6/p1666217128557719

I think it extends RuntimeException which means Temporal knows to retry activities that fail with it as a cause, but it isn't super clear

@@ -0,0 +1,37 @@
/*
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here's the OSS implementation of the GeographyMapper. In Cloud, this class will be overridden with a @Replaces annotation

Copy link
Contributor

Choose a reason for hiding this comment

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

For my own understanding too, since I haven't had a chance to work much with micronaut (need to change that!).

How do the @replace and @primary annotations interact?

Copy link
Contributor

Choose a reason for hiding this comment

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

@davinchia They are two different options for the same result. Any bean marked @Primary will always win. @Replace is used to take the place of an existing bean of the same type. I haven't played with it, but I suspect that @Replace wouldn't work if no other bean exists of that type, but @Primary would. Generally, one is a bit more loose than the other, so it really depends on if we have more than 2 versions, as we won't want to mark two of the three of the same type with @Primary.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sounds like we should default to @primary and use @replace on a needs-to basis

Copy link
Contributor

Choose a reason for hiding this comment

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

@davinchia That is my assessment as well.

@pmossman pmossman requested a review from jdpgrailsdev October 19, 2022 00:24
@pmossman
Copy link
Contributor Author

@jdpgrailsdev @davinchia I think this should be ready for review in tandem with the Cloud PR

*/
@Singleton
@Slf4j
@AllArgsConstructor
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Our recommendation is to not use Lombok and instead create an explicit constructor with the beans to be injected. This allows us to use annotations on the fields should that become necessary.

Copy link
Contributor

@davinchia davinchia Oct 19, 2022

Choose a reason for hiding this comment

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

@jdpgrailsdev for my knowledge, what does 'allows us to use annotations on the fields should that become necessary' mean?

(I understand and agree on not mixing constructor annotations from separate AOP frameworks for clarity/best practices.)

Copy link
Contributor

Choose a reason for hiding this comment

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

@davinchia With the Lombok generated constructor, there is no code for us to modify if we end up needing to add a @Qualifier annotation to specify which version of a singleton to inject, nor is there the ability for us to use @Value or @Property to inject configuration values via the constructor. Put another way, the Lombok generated constructor only works for constructor-based injection if we do not need to annotate any of the parameters in order for Micronaut to make the correct injection.

Copy link
Contributor

Choose a reason for hiding this comment

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

Got it. Thanks for explaining.

I think we should also start phasing out Lombok in our system for clarity. Does Micronaut have an @Slf4j annotation equivalent? I believe these two are the main Lombok annotations we use.

Copy link
Contributor

Choose a reason for hiding this comment

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

@davinchia No, not that I am aware of. It provides the configuration of the logging system, but the use of a logger is up to the developer. I'm not sure that the @Slf4j annotation really saves us a whole lot, as declaring a logger is a 1 line statement, much like the annotation.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah. I think the benefit of the annotation is mostly not need to remember to type the long string and the hideous class import - all cosmetic.

MIcronaut docs do indicate some clashing of Lombok and Micronaut - let's get rid of Lombok!

Copy link
Contributor

@jdpgrailsdev jdpgrailsdev left a comment

Choose a reason for hiding this comment

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

:shipit:

@pmossman pmossman force-pushed the parker/router-service-using-db branch from a5430be to c6b30ea Compare October 19, 2022 15:08
@pmossman pmossman temporarily deployed to more-secrets October 19, 2022 15:10 Inactive
@pmossman pmossman force-pushed the parker/router-service-using-db branch from c6b30ea to 9c79c5a Compare October 19, 2022 15:20
@pmossman pmossman temporarily deployed to more-secrets October 19, 2022 15:22 Inactive
@@ -579,16 +579,6 @@ public interface Configs {
*/
boolean shouldRunConnectionManagerWorkflows();

// Worker - Control Plane configs
Copy link
Contributor

Choose a reason for hiding this comment

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

+1

private final ConfigRepository configRepository;
private final GeographyMapper geographyMapper;

public RouterService(final ConfigRepository configRepository, final GeographyMapper geographyMapper) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is where Micronaut will inject the Cloud specific bean?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes. It will inject which ever implementation of the GeographyMapper wins. In OSS, this will be the default implementation (the only one present). In cloud, both are present on the classpath, but only the one provided by the cloud-worker library will win because of the Primary annotation.

return new RouteToSyncTaskQueueOutput(taskQueueForConnectionId);
return new RouteToSyncTaskQueueOutput(taskQueueForConnectionId);
} catch (final IOException e) {
throw new RetryableException(e);
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: log.warn here?

public class DefaultGeographyMapper implements GeographyMapper {

@VisibleForTesting
static final String DEFAULT_SYNC_TASK_QUEUE = TemporalJobType.SYNC.name();
Copy link
Contributor

Choose a reason for hiding this comment

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

+1

* Maps a {@link Geography} to a Temporal Task Queue that should be used to run syncs for the given
* Geography.
*/
public interface GeographyMapper {
Copy link
Contributor

Choose a reason for hiding this comment

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

Thinking out loud:

Would a better name not include Geography? Thinking about the future where we want the input to getTaskQueue to not be tied to geography. Maybe QueueMapper?

Landing what we have now and evolving this later is also okay to me.


/**
* If this test fails, it likely means that a new value was added to the {@link Geography} enum. A
* new entry must be added to {@link DefaultGeographyMapper#GEOGRAPHY_TASK_QUEUE_MAP} to get this
Copy link
Contributor

Choose a reason for hiding this comment

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

+1

Copy link
Contributor

@davinchia davinchia left a comment

Choose a reason for hiding this comment

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

Thanks @pmossman

Both the code comments and the PR comments made it very easy to review.

I have one medium comment about naming of the geography mapper. I have some smaller comments for my own understanding.

None of these are blocking. We can iterate on a follow up PR.

@pmossman pmossman temporarily deployed to more-secrets October 20, 2022 00:16 Inactive
@pmossman pmossman force-pushed the parker/router-service-using-db branch from 39cf2ab to 0301e31 Compare October 20, 2022 00:45
@pmossman pmossman temporarily deployed to more-secrets October 20, 2022 00:47 Inactive
@pmossman pmossman force-pushed the parker/router-service-using-db branch from 0301e31 to 9a5ab5a Compare October 20, 2022 01:55
@pmossman pmossman temporarily deployed to more-secrets October 20, 2022 01:57 Inactive
move geography map to a helper that can be overridden with a separate implementation in cloud

format

pmd

fix import

move geography mapper interface to airbyte-commons-temporal
@pmossman pmossman force-pushed the parker/router-service-using-db branch from 9a5ab5a to 53045c1 Compare October 20, 2022 19:00
@pmossman pmossman temporarily deployed to more-secrets October 20, 2022 19:02 Inactive
@pmossman pmossman temporarily deployed to more-secrets October 20, 2022 20:10 Inactive
@pmossman pmossman temporarily deployed to more-secrets October 20, 2022 20:14 Inactive
@pmossman pmossman merged commit 4e236b5 into master Oct 20, 2022
@pmossman pmossman deleted the parker/router-service-using-db branch October 20, 2022 21:48
jhammarstedt pushed a commit to jhammarstedt/airbyte that referenced this pull request Oct 31, 2022
* router service uses geography in database instead of env var

move geography map to a helper that can be overridden with a separate implementation in cloud

format

pmd

fix import

move geography mapper interface to airbyte-commons-temporal

* add DefaultGeographyMapper back in

* remove all args constructor and extranneous import

* rename GeographyMapper to TaskQueueMapper
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/platform issues related to the platform area/worker Related to worker
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants