-
-
Notifications
You must be signed in to change notification settings - Fork 287
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: implement IndexedGossipQueue #5803
Conversation
Performance Report✔️ no performance regression detected Full benchmark results
|
* If not, pick the last key | ||
*/ | ||
next(): T[] | null { | ||
let key: string | null = this.minChunkSizeKeys.last(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this approach is best, consider this case:
- a key receives minChunkSize-1 items at time T1 and then 1 extra item at time T2
- It is appended to minChunkSizeKeys at time T2 and will be picked up first, but most of its items are at time T1
Similarly if a key does not receive minChunkSize it will always be de-prioritized. This approach risks respecting FIFO for some load patterns.
The goals for a FIFO queue with indexing that intends to batch should be:
- Prioritize latest items
- Buffer items to allow batching, but limit buffering by max wait or max length
For 1. in batches, what decide the timeliness of a batch?
- First arrival
- Latest arrival
- Avg of items
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, this is not ideal. Initially I did like this:
- always pick the last item (like LIFO)
- process it along with
min(64, number of messages with same data/key)
the performance is far from the current approach since it can't batch much messages. I think it's not easy to pick a strategy, we need to:
- define some criterias to pick a strategy, one is: job wait time + job time + avg(forwarded messages)
- do some dynamic configurations here, configure it at runtime and compare
It's not easy to enforce FIFO and fairness rules having multiple list of objects that arrive at different times. We do FIFO for attestations because the most recent attestations have the most value to us. Given a list of single-bit gossip attestations (assuming all valid) their value is equal the sum of One approach that would be fair but maybe expensive is to compute this "score" everytime type MsgList = {
avgRecvTimestampMs: number;
items: GossipMsg[];
};
type GossipMsgId = string;
type GossipMsg = any;
const msgListScore = (a: MsgList): number => a.items.length / Math.max(1000, Date.now() - a.avgRecvTimestampMs);
const getKey = (_: GossipMsg): GossipMsgId => "TODO";
class Queue {
queuesMap: Map<GossipMsgId, MsgList>;
queuesList: MsgList[];
add(item: GossipMsg): void {
const key = getKey(item);
let queue = this.queuesMap.get(key);
if (!queue) {
queue = {avgRecvTimestampMs: Date.now(), items: [item]};
this.queuesMap.set(key, queue);
} else {
queue.items.push(item);
// Compute average adding 1 value: avg = (avg * N + x) / (N + 1)
queue.avgRecvTimestampMs =
(queue.items.length * queue.avgRecvTimestampMs + Date.now()) / (queue.items.length + 1);
}
}
getNext(): GossipMsg[] | undefined {
// Sort in place by score, can be optimized runing this sometimes only
this.queuesList.sort((a, b) => msgListScore(a) - msgListScore(b));
return this.queuesList.shift()?.items;
}
} |
@dapplion yes that's expensive, tested the |
please @tuyennhv do not post spiky graphs, post either histograms or % of values above a certain threshold, or an avg_over_time |
The queue must have some mechanism to pick up groups of attestation datas that do not reach the minimum count. |
the current mechanism works as below:
with
@dapplion what do you expect, or want to improve with the above example? I can give it a try in a real node |
Let's go with this and have histogram metrics to measure delay in the queue since first item |
🎉 This PR is included in v1.11.0 🎉 |
Motivation
Description
GossipQueue
interface, the current implementation isLinearGossipQueue
. This does not affect the current performance of node since noone is using the new gossip queue for nowIndexedGossipQueue
part of #5416