Skip to content

Consider a timeout heap #6

Closed
Closed
@Raynos

Description

@Raynos

We implemented a timeout Heap datastructure at uber ( https://github.com/uber/tchannel-node/blob/master/time_heap.js ).

It supports a minTimeout function or number which we use like

    // for processing operation timeouts
    this.timeHeap = this.options.timeHeap || new TimeHeap({
        timers: this.timers,
        // TODO: do we still need/want fuzzing?
        minTimeout: fuzzedMinTimeout
    });

    function fuzzedMinTimeout() {
        var fuzz = self.options.timeoutFuzz;
        if (fuzz) {
            fuzz = Math.floor(fuzz * (self.random() - 0.5));
        }
        return self.options.timeoutCheckInterval + fuzz;
    }

Using a heap is better then an array or linked list for nuanced reasons I don't quite understand.

But what is better then setTimeout is to say

"we will set a min timeout for 100ms and if a lot of "timers" expire in this minTimeout window then we will fire their callback function with upto 100ms delay.

This basically means that if you have 10,000 sockets you are garantueed a maximum of 10 setTimeout calls on the libuv event loop every 10 seconds no matter what load there is.

If you have a 5s or 30s timeout on sockets then an extra 100ms delay on the socket.destroy() is not a big deal in our usecase.

Also timeoutFuzz is a super awesome feature to avoid "thundering herd" problems, if you restart all your servers at the same time they might all set a timeout to expire exactly 10s in the future, by adding 50ms fuzz to either side you can spread out a "thundering reconnection herd" over a 100ms window in time instead of a 0ms window in time.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions