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

feat(server): Implement an HTTP outcomes producer #592

Merged
merged 17 commits into from
Jun 9, 2020

Conversation

RaduW
Copy link
Contributor

@RaduW RaduW commented May 28, 2020

Relay installations that use the full (all features) binary may be configured to operate with processing disabled.
When operating with processing disabled they should forward the outcomes to the http endpoint of the upstream instead
of placing them on the outcomes kafka topic.

@RaduW RaduW requested a review from a team May 28, 2020 15:00
@RaduW RaduW marked this pull request as draft May 28, 2020 15:06
@RaduW RaduW force-pushed the feat/extend-kafka-outcomes-producer branch 2 times, most recently from 8c75fb2 to 31f5a51 Compare June 2, 2020 10:35
@RaduW RaduW marked this pull request as ready for review June 3, 2020 09:02
@jan-auer jan-auer changed the title feat(server) Extend Kafka OutcomesProducer to work with processing disabled flag. feat(server): Extend Kafka OutcomesProducer to work with processing disabled flag Jun 3, 2020
@RaduW RaduW requested a review from jan-auer June 3, 2020 17:55
@RaduW RaduW force-pushed the feat/extend-kafka-outcomes-producer branch 2 times, most recently from d0d7835 to 1151088 Compare June 3, 2020 18:00
Copy link
Member

@jan-auer jan-auer left a comment

Choose a reason for hiding this comment

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

Thanks, batching and HTTP implementation looks fine.

Up for discussion: There is a tiny bit of "duplication" going on since both implementations are repeating the same internal fields, and thus they need to share their implementation. Would it be possible to rather compose the actors or at least the structs?

Here is some shortened code to illustrate that using an Addr:

mod http {
  pub struct HttpOutcomeProducer { 
    // http stuff
  }

  impl Actor for HttpOutcomeProducer { ... }
  impl Handler<TrackRawOutcome> for HttpOutcomeProducer { ... }
}

#[cfg(feature = "processing")]
mod processing {
  pub struct KafkaOutcomeProducer {
    http: Addr<HttpOutcomeProducer>,
    // kafka stuff
  }

  impl Actor for KafkaOutcomeProducer { ... }
  impl Handler<TrackRawOutcome> for KafkaOutcomeProducer {
    fn handle() {
      if self.config.processing_enabled() { 
        /* kafka stuff */
      } else { 
        self.http.do_send(message)
      }
    }
  }
}

#[cfg(feature = "processing")]
pub type OutcomeProducer = kafka::KafkaOutcomeProducer;
#[cfg(not(feature = "processing"))]
pub type OutcomeProducer = http::HttpOutcomeProducer;

The other option would be to hold HttpOutcomeProducer directly, and call a http method on it.

relay-config/src/config.rs Outdated Show resolved Hide resolved
relay-config/src/config.rs Show resolved Hide resolved
relay-server/src/actors/outcome.rs Show resolved Hide resolved
relay-server/src/actors/outcome.rs Outdated Show resolved Hide resolved
relay-server/src/actors/outcome.rs Outdated Show resolved Hide resolved
relay-server/src/actors/outcome.rs Show resolved Hide resolved
relay-server/src/actors/outcome.rs Show resolved Hide resolved
Copy link
Member

@untitaker untitaker left a comment

Choose a reason for hiding this comment

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

I agree with Jan's comment about nesting HTTP outcome producer into the other one.

self.unsent_outcomes.push(message);
if self.unsent_outcomes.len() >= self.config.max_outcome_batch_size() {
if let Some(send_outcomes_future) = self.send_outcomes_future {
context.cancel_future(send_outcomes_future);
Copy link
Member

Choose a reason for hiding this comment

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

I am not 100% sure if this may cancel a HTTP request mid-flight and run the risk of double-sending outcomes. Even if this is an actor future, such a future only has exclusive access to self during a poll, not during the lifetime of the future.

Also doesn't this generally cause us to drop a preceding batch of outcomes if we run into the batch size limit again? Seems like that would happen instantly under sustained traffic.

Copy link
Member

@jan-auer jan-auer Jun 7, 2020

Choose a reason for hiding this comment

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

The SpawnHandle is removed from the struct in line 326 the moment that send_batch runs before starting an HTTP request. self.send_outcomes_future is only there to synchronize between the batch limit and the batch delay. Once the request starts, it will send whatever is queued, which is guaranteed to be lte the batch size limit.

I think for those reasons, neither of the two cases apply. Can you double-check?

Copy link
Member

Choose a reason for hiding this comment

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

I see, so self.send_outcomes_future is only being Some if we're counting down from the timeout, not when the request is in flight. That makes sense and you're right. Can we somehow make it explicit that nothing that may suspend the future (such as more IO) may be added before line 326?

Copy link
Member

Choose a reason for hiding this comment

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

Additionally we can also rename the field to something like pending_flush to make this more clear?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok, changed send_outcomes_future to pending_flush_handle.

Didn't quite get what you are asking at:

Can we somehow make it explicit that nothing that may suspend the future (such as more IO) may be added before line 326?

Copy link
Member

Choose a reason for hiding this comment

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

I think he meant to write into the comment that nothing should go before the check of pending_flush_handle in send_batch

relay-server/src/actors/outcome.rs Outdated Show resolved Hide resolved
tests/integration/fixtures/mini_sentry.py Show resolved Hide resolved
Copy link
Member

@untitaker untitaker left a comment

Choose a reason for hiding this comment

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

actually wanted to request changes because I believe one of the points I made may be a critical bug

@jan-auer jan-auer changed the title feat(server): Extend Kafka OutcomesProducer to work with processing disabled flag feat(server): Implement an HTTP outcomes producer Jun 8, 2020
@RaduW RaduW force-pushed the feat/extend-kafka-outcomes-producer branch from b60de4d to c5885c4 Compare June 8, 2020 14:15
@RaduW RaduW requested review from jan-auer and untitaker June 8, 2020 14:16
relay-server/src/actors/outcome.rs Outdated Show resolved Hide resolved
relay-config/src/config.rs Outdated Show resolved Hide resolved
@RaduW RaduW force-pushed the feat/extend-kafka-outcomes-producer branch from 995e817 to bc6cc3b Compare June 8, 2020 14:42
Copy link
Member

@jan-auer jan-auer left a comment

Choose a reason for hiding this comment

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

G2G once the linter is fixed, thanks a lot!

@jan-auer jan-auer dismissed untitaker’s stale review June 8, 2020 18:42

Review feedback has been addressed.

@RaduW RaduW merged commit 475e623 into master Jun 9, 2020
@RaduW RaduW deleted the feat/extend-kafka-outcomes-producer branch June 9, 2020 07:15
jan-auer added a commit that referenced this pull request Jun 9, 2020
* master:
  ref(quotas): Remove support for legacy quotas (#616)
  feat(server): Implement an HTTP outcomes producer (#592)
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.

None yet

3 participants