private keepalive()

in src/lease.ts [312:364]


  private keepalive() {
    // When the cluster goes down, we keep trying to reconnect. But if we're
    // far past the end of our key's TTL, there's no way we're going to be
    // able to renew it. Fire a "lost".
    if (Date.now() - this.lastKeepAlive > 2 * 1000 * this.ttl) {
      this.close();
      this.emit(
        'lost',
        new EtcdLeaseInvalidError('We lost connection to etcd and our lease has expired.'),
      );
      return;
    }

    this.client
      .leaseKeepAlive()
      .then(stream => {
        if (this.innerState === LeaseState.Revoked) {
          return stream.end();
        }

        // this is what the official Go client uses, good enough:
        const keepAliveInterval = (1000 * this.ttl) / 3;
        const keepaliveTimer = setInterval(() => this.fireKeepAlive(stream), keepAliveInterval);
        const keepAliveTimeout = debounce(1000 * this.ttl, () =>
          this.handleKeepaliveError(new GRPCCancelledError('GRPC watch stream has timed out.')),
        );

        this.teardown = () => {
          this.teardown = () => undefined;
          keepAliveTimeout.cancel();
          clearInterval(keepaliveTimer);
          stream.end();
        };

        keepAliveTimeout(); // start the debounce

        stream
          .on('error', err => this.handleKeepaliveError(err))
          .on('data', res => {
            if (leaseExpired(res)) {
              return this.handleKeepaliveError(new EtcdLeaseInvalidError(res.ID));
            }

            this.lastKeepAlive = Date.now();
            keepAliveTimeout();
            this.emit('keepaliveSucceeded', res);
          });

        this.emit('keepaliveEstablished');
        return this.fireKeepAlive(stream);
      })
      .catch(err => this.handleKeepaliveError(err));
  }