|
|
|
|
@ -14,6 +14,8 @@
|
|
|
|
|
#define STREAM_OFFER_TTL_MS 60000 |
|
|
|
|
#define STREAM_MIGRATION_TIMEOUT_MS 5000 |
|
|
|
|
#define STREAM_BOOTSTRAP_RELAY_MS 100 |
|
|
|
|
#define STREAM_AVAILABILITY_RETRY_MS 100 |
|
|
|
|
#define STREAM_AVAILABILITY_WAIT_MS 5000 |
|
|
|
|
#define STREAM_PROBLEM_PENALTY_MS 1000 |
|
|
|
|
#define STREAM_HOP_PENALTY_MS 3 |
|
|
|
|
|
|
|
|
|
@ -26,7 +28,7 @@ struct stream_offer {
|
|
|
|
|
}; |
|
|
|
|
struct stream_supplier { |
|
|
|
|
struct stream_supplier *next; |
|
|
|
|
uint64_t node, cycle, retry_ms; |
|
|
|
|
uint64_t node, cycle, retry_ms, availability_retry_ms, availability_until_ms; |
|
|
|
|
uint64_t local_epoch, peer_epoch; |
|
|
|
|
struct STREAM_RECEIVE *probe; |
|
|
|
|
struct stream_offer *offers; |
|
|
|
|
@ -137,6 +139,15 @@ static void probes_poll(struct stream_optimizer *o, struct STREAM_HANDLE *h, uin
|
|
|
|
|
if (!info.info_ready && info.state != STREAM_RECEIVE_CLOSED) continue; |
|
|
|
|
if (info.state == STREAM_RECEIVE_CLOSED) { |
|
|
|
|
s->offers[s->probe_sub].info.info_ms = 0; |
|
|
|
|
if (info.reason == STREAM_REASON_POSITION) { |
|
|
|
|
if (!s->availability_until_ms) s->availability_until_ms = now + STREAM_AVAILABILITY_WAIT_MS; |
|
|
|
|
if (now < s->availability_until_ms && !s->availability_retry_ms) { |
|
|
|
|
s->availability_retry_ms = now + STREAM_AVAILABILITY_RETRY_MS; |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_STREAM, "stream supplier buffer pending source=%llx peer=%llx sub=%u retry_ms=%u", |
|
|
|
|
(unsigned long long)o->descriptor.source_node_id, (unsigned long long)s->node, |
|
|
|
|
s->probe_sub, STREAM_AVAILABILITY_RETRY_MS); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (info.reason == STREAM_REASON_TRANSPORT || info.reason == STREAM_REASON_MEMBER || info.reason == STREAM_REASON_PROTOCOL) { |
|
|
|
|
s->failures++; s->retry_ms = now + backoff(s->failures); |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_STREAM, "stream optimizer probe closed source=%llx peer=%llx sub=%u reason=%d" |
|
|
|
|
@ -174,6 +185,12 @@ static void probes_poll(struct stream_optimizer *o, struct STREAM_HANDLE *h, uin
|
|
|
|
|
static void probes_schedule(struct stream_optimizer *o, struct STREAM_HANDLE *h, uint64_t now) { |
|
|
|
|
unsigned pending = 0, active = 0; |
|
|
|
|
for (struct stream_supplier *s = o->suppliers; s; s = s->next) { |
|
|
|
|
if (!s->probe && s->availability_retry_ms && now >= s->availability_retry_ms) { |
|
|
|
|
s->availability_retry_ms = 0; |
|
|
|
|
if (s->compatible && now < s->availability_until_ms && now >= s->retry_ms) { |
|
|
|
|
s->cycle = 0; o->schedule.next_ms = 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (s->probe) active++; |
|
|
|
|
if (now < s->retry_ms) s->cycle = o->schedule.cycle; |
|
|
|
|
if (s->compatible && s->cycle != o->schedule.cycle) pending++; |
|
|
|
|
|