Skip to content

Commit 1151088

Browse files
committed
incorporate code review comments
finish integration tests
1 parent 43995f6 commit 1151088

File tree

4 files changed

+201
-78
lines changed

4 files changed

+201
-78
lines changed

relay-config/src/config.rs

+32-17
Original file line numberDiff line numberDiff line change
@@ -351,15 +351,6 @@ pub struct Relay {
351351
pub tls_identity_path: Option<PathBuf>,
352352
/// Password for the PKCS12 archive.
353353
pub tls_identity_password: Option<String>,
354-
/// Controls whether outcomes will be emitted when processing is disabled.
355-
/// Processing relays always emit outcomes (for backwards compatibility).
356-
pub emit_outcomes: bool,
357-
/// The maximum number of outcomes that are batched before being sent
358-
/// via http to the upstream (only applies to non processing relays)
359-
pub max_outcome_batch_size: usize,
360-
/// The maximum time interval (in milliseconds) that an outcome may be batched
361-
/// via http to the upstream (only applies to non processing relays)
362-
pub max_outcome_interval_millsec: u64,
363354
}
364355

365356
impl Default for Relay {
@@ -372,9 +363,6 @@ impl Default for Relay {
372363
tls_port: None,
373364
tls_identity_path: None,
374365
tls_identity_password: None,
375-
emit_outcomes: false,
376-
max_outcome_batch_size: 1000,
377-
max_outcome_interval_millsec: 500,
378366
}
379367
}
380368
}
@@ -718,6 +706,31 @@ impl Default for Processing {
718706
}
719707
}
720708

709+
/// Outcome generation specific configuration values.
710+
#[derive(Serialize, Deserialize, Debug)]
711+
#[serde(default)]
712+
pub struct Outcomes {
713+
/// Controls whether outcomes will be emitted when processing is disabled.
714+
/// Processing relays always emit outcomes (for backwards compatibility).
715+
pub emit_outcomes: bool,
716+
/// The maximum number of outcomes that are batched before being sent
717+
/// via http to the upstream (only applies to non processing relays)
718+
pub max_outcome_batch_size: usize,
719+
/// The maximum time interval (in milliseconds) that an outcome may be batched
720+
/// via http to the upstream (only applies to non processing relays)
721+
pub max_outcome_interval_millsec: u64,
722+
}
723+
724+
impl Default for Outcomes {
725+
fn default() -> Self {
726+
Outcomes {
727+
emit_outcomes: false,
728+
max_outcome_batch_size: 1000,
729+
max_outcome_interval_millsec: 500,
730+
}
731+
}
732+
}
733+
721734
/// Minimal version of a config for dumping out.
722735
#[derive(Serialize, Deserialize, Debug, Default)]
723736
pub struct MinimalConfig {
@@ -765,6 +778,8 @@ struct ConfigValues {
765778
sentry: Sentry,
766779
#[serde(default)]
767780
processing: Processing,
781+
#[serde(default)]
782+
outcomes: Outcomes,
768783
}
769784

770785
impl ConfigObject for ConfigValues {
@@ -1052,17 +1067,17 @@ impl Config {
10521067

10531068
/// Returns the emit_outcomes flag
10541069
pub fn emit_outcomes(&self) -> bool {
1055-
self.values.relay.emit_outcomes
1070+
self.values.outcomes.emit_outcomes
10561071
}
10571072

10581073
/// Returns the maximum number of outcomes that are batched before being sent
10591074
pub fn max_outcome_batch_size(&self) -> usize {
1060-
self.values.relay.max_outcome_batch_size
1075+
self.values.outcomes.max_outcome_batch_size
10611076
}
10621077

1063-
/// Returns the maximum interval (in milliseconds) that an outcome may be batched
1064-
pub fn max_outcome_interval_millsec(&self) -> u64 {
1065-
self.values.relay.max_outcome_interval_millsec
1078+
/// Returns the maximum interval that an outcome may be batched
1079+
pub fn max_outcome_interval(&self) -> Duration {
1080+
Duration::from_millis(self.values.outcomes.max_outcome_interval_millsec)
10661081
}
10671082

10681083
/// Returns the log level.

relay-server/src/actors/outcome.rs

+24-19
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
77
use std::net::IpAddr;
88
use std::sync::Arc;
9-
use std::time::Duration;
109
use std::time::Instant;
1110

1211
use actix::prelude::*;
@@ -15,15 +14,14 @@ use chrono::SecondsFormat;
1514
use futures::future::Future;
1615
use serde::{Deserialize, Serialize};
1716

18-
use relay_common::ProjectId;
17+
use relay_common::{LogError, ProjectId};
1918
use relay_config::Config;
2019
use relay_filter::FilterStatKey;
2120
use relay_general::protocol::EventId;
2221
use relay_quotas::{ReasonCode, Scoping};
2322

2423
use crate::actors::upstream::SendQuery;
2524
use crate::actors::upstream::{UpstreamQuery, UpstreamRelay};
26-
use crate::utils::run_later;
2725
use crate::ServerError;
2826

2927
// Choose the outcome module implementation (either processing or non-processing).
@@ -321,20 +319,28 @@ impl Message for TrackRawOutcome {
321319
/// Common implementation for both processing and non-processing
322320
impl OutcomeProducer {
323321
fn send_batch(&mut self, context: &mut Context<Self>) {
324-
log::trace!("Sending outcome batch");
322+
log::trace!("sending outcome batch");
323+
324+
//the future should be either canceled (if we are called with a full batch)
325+
// or already called (if we are called by a timeout)
326+
self.send_outcomes_future = None;
327+
328+
if self.unsent_outcomes.len() == 0 {
329+
log::warn!("unexpected send_batch scheduled with no outcomes to send.");
330+
return;
331+
}
332+
325333
let request = SendOutcomes {
326334
outcomes: self.unsent_outcomes.drain(..).collect(),
327335
};
328-
self.send_scheduled = false;
329336

330-
//BUG (RaduW) the future is never resolved, there is no tracing error.
331337
self.upstream
332338
.send(SendQuery(request))
333339
.map(|_| {
334340
log::trace!("outcome batch sent.");
335341
})
336-
.map_err(|_| {
337-
log::warn!("outcome batch sending failed!");
342+
.map_err(|error| {
343+
log::error!("outcome batch sending failed with: {}", LogError(&error));
338344
})
339345
.into_actor(self)
340346
.spawn(context);
@@ -348,14 +354,13 @@ impl OutcomeProducer {
348354
log::trace!("Batching outcome");
349355
self.unsent_outcomes.push(message);
350356
if self.unsent_outcomes.len() >= self.config.max_outcome_batch_size() {
357+
if let Some(send_outcomes_future) = self.send_outcomes_future {
358+
context.cancel_future(send_outcomes_future);
359+
}
351360
self.send_batch(context)
352-
} else if !self.send_scheduled {
353-
self.send_scheduled = true;
354-
run_later(
355-
Duration::from_millis(self.config.max_outcome_interval_millsec()),
356-
Self::send_batch,
357-
)
358-
.spawn(context)
361+
} else if self.send_outcomes_future.is_none() {
362+
self.send_outcomes_future =
363+
Some(context.run_later(self.config.max_outcome_interval(), Self::send_batch));
359364
}
360365

361366
Ok(())
@@ -407,7 +412,7 @@ mod processing {
407412
producer: Option<ThreadedProducer>,
408413
pub(super) upstream: Addr<UpstreamRelay>,
409414
pub(super) unsent_outcomes: Vec<TrackRawOutcome>,
410-
pub(super) send_scheduled: bool,
415+
pub(super) send_outcomes_future: Option<SpawnHandle>,
411416
}
412417

413418
impl OutcomeProducer {
@@ -433,7 +438,7 @@ mod processing {
433438
producer: future_producer,
434439
upstream,
435440
unsent_outcomes: Vec::new(),
436-
send_scheduled: false,
441+
send_outcomes_future: None,
437442
})
438443
}
439444

@@ -524,7 +529,7 @@ mod non_processing {
524529
pub(super) config: Arc<Config>,
525530
pub(super) upstream: Addr<UpstreamRelay>,
526531
pub(super) unsent_outcomes: Vec<TrackRawOutcome>,
527-
pub(super) send_scheduled: bool,
532+
pub(super) send_outcomes_future: Option<SpawnHandle>,
528533
}
529534

530535
impl OutcomeProducer {
@@ -536,7 +541,7 @@ mod non_processing {
536541
config,
537542
upstream,
538543
unsent_outcomes: Vec::new(),
539-
send_scheduled: false,
544+
send_outcomes_future: None,
540545
})
541546
}
542547
}

tests/integration/fixtures/mini_sentry.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,9 @@ def outcomes():
160160
if relay_id not in authenticated_relays:
161161
abort(403, "relay not registered")
162162

163-
outcomes_batch = flask_request.json()
163+
outcomes_batch = flask_request.json
164164
sentry.captured_outcomes.put(outcomes_batch)
165+
return jsonify({})
165166

166167
@app.errorhandler(500)
167168
def fail(e):

0 commit comments

Comments
 (0)