Move heart and AuthType out of http

This file is going to get blasted in favor of Express.
This commit is contained in:
Asher 2020-10-15 17:00:21 -05:00
parent dcb303a437
commit 2928d362fa
No known key found for this signature in database
GPG Key ID: D63C1EF81242354A
6 changed files with 59 additions and 55 deletions

View File

@ -1,4 +1,5 @@
import { HttpProvider, HttpResponse, Heart, HttpProviderOptions } from "../http" import { Heart } from "../heart"
import { HttpProvider, HttpProviderOptions, HttpResponse } from "../http"
/** /**
* Check the heartbeat. * Check the heartbeat.

View File

@ -2,7 +2,8 @@ import * as http from "http"
import * as limiter from "limiter" import * as limiter from "limiter"
import * as querystring from "querystring" import * as querystring from "querystring"
import { HttpCode, HttpError } from "../../common/http" import { HttpCode, HttpError } from "../../common/http"
import { AuthType, HttpProvider, HttpProviderOptions, HttpResponse, Route } from "../http" import { AuthType } from "../cli"
import { HttpProvider, HttpProviderOptions, HttpResponse, Route } from "../http"
import { hash, humanPath } from "../util" import { hash, humanPath } from "../util"
interface LoginPayload { interface LoginPayload {

View File

@ -4,9 +4,13 @@ import yaml from "js-yaml"
import * as os from "os" import * as os from "os"
import * as path from "path" import * as path from "path"
import { Args as VsArgs } from "../../lib/vscode/src/vs/server/ipc" import { Args as VsArgs } from "../../lib/vscode/src/vs/server/ipc"
import { AuthType } from "./http"
import { canConnect, generateCertificate, generatePassword, humanPath, paths } from "./util" import { canConnect, generateCertificate, generatePassword, humanPath, paths } from "./util"
export enum AuthType {
Password = "password",
None = "none",
}
export class Optional<T> { export class Optional<T> {
public constructor(public readonly value?: T) {} public constructor(public readonly value?: T) {}
} }

46
src/node/heart.ts Normal file
View File

@ -0,0 +1,46 @@
import { logger } from "@coder/logger"
import { promises as fs } from "fs"
/**
* Provides a heartbeat using a local file to indicate activity.
*/
export class Heart {
private heartbeatTimer?: NodeJS.Timeout
private heartbeatInterval = 60000
public lastHeartbeat = 0
public constructor(private readonly heartbeatPath: string, private readonly isActive: () => Promise<boolean>) {}
public alive(): boolean {
const now = Date.now()
return now - this.lastHeartbeat < this.heartbeatInterval
}
/**
* Write to the heartbeat file if we haven't already done so within the
* timeout and start or reset a timer that keeps running as long as there is
* activity. Failures are logged as warnings.
*/
public beat(): void {
if (!this.alive()) {
logger.trace("heartbeat")
fs.writeFile(this.heartbeatPath, "").catch((error) => {
logger.warn(error.message)
})
this.lastHeartbeat = Date.now()
if (typeof this.heartbeatTimer !== "undefined") {
clearTimeout(this.heartbeatTimer)
}
this.heartbeatTimer = setTimeout(() => {
this.isActive()
.then((active) => {
if (active) {
this.beat()
}
})
.catch((error) => {
logger.warn(error.message)
})
}, this.heartbeatInterval)
}
}
}

View File

@ -13,6 +13,8 @@ import * as tls from "tls"
import * as url from "url" import * as url from "url"
import { HttpCode, HttpError } from "../common/http" import { HttpCode, HttpError } from "../common/http"
import { arrayify, normalize, Options, plural, split, trimSlashes } from "../common/util" import { arrayify, normalize, Options, plural, split, trimSlashes } from "../common/util"
import { AuthType } from "./cli"
import { Heart } from "./heart"
import { SocketProxyProvider } from "./socket" import { SocketProxyProvider } from "./socket"
import { getMediaMime, paths } from "./util" import { getMediaMime, paths } from "./util"
@ -27,11 +29,6 @@ interface AuthPayload extends Cookies {
key?: string[] key?: string[]
} }
export enum AuthType {
Password = "password",
None = "none",
}
export type Query = { [key: string]: string | string[] | undefined } export type Query = { [key: string]: string | string[] | undefined }
export interface ProxyOptions { export interface ProxyOptions {
@ -390,50 +387,6 @@ export abstract class HttpProvider {
} }
} }
/**
* Provides a heartbeat using a local file to indicate activity.
*/
export class Heart {
private heartbeatTimer?: NodeJS.Timeout
private heartbeatInterval = 60000
public lastHeartbeat = 0
public constructor(private readonly heartbeatPath: string, private readonly isActive: () => Promise<boolean>) {}
public alive(): boolean {
const now = Date.now()
return now - this.lastHeartbeat < this.heartbeatInterval
}
/**
* Write to the heartbeat file if we haven't already done so within the
* timeout and start or reset a timer that keeps running as long as there is
* activity. Failures are logged as warnings.
*/
public beat(): void {
if (!this.alive()) {
logger.trace("heartbeat")
fs.outputFile(this.heartbeatPath, "").catch((error) => {
logger.warn(error.message)
})
this.lastHeartbeat = Date.now()
if (typeof this.heartbeatTimer !== "undefined") {
clearTimeout(this.heartbeatTimer)
}
this.heartbeatTimer = setTimeout(() => {
this.isActive()
.then((active) => {
if (active) {
this.beat()
}
})
.catch((error) => {
logger.warn(error.message)
})
}, this.heartbeatInterval)
}
}
}
export interface HttpProvider0<T> { export interface HttpProvider0<T> {
new (options: HttpProviderOptions): T new (options: HttpProviderOptions): T
} }

View File

@ -3,12 +3,11 @@ import * as fs from "fs-extra"
import * as http from "http" import * as http from "http"
import * as path from "path" import * as path from "path"
import { LatestResponse, UpdateHttpProvider } from "../src/node/app/update" import { LatestResponse, UpdateHttpProvider } from "../src/node/app/update"
import { AuthType } from "../src/node/http" import { AuthType } from "../src/node/cli"
import { SettingsProvider, UpdateSettings } from "../src/node/settings" import { SettingsProvider, UpdateSettings } from "../src/node/settings"
import { tmpdir } from "../src/node/util" import { tmpdir } from "../src/node/util"
describe("update", () => { describe.skip("update", () => {
return
let version = "1.0.0" let version = "1.0.0"
let spy: string[] = [] let spy: string[] = []
const server = http.createServer((request: http.IncomingMessage, response: http.ServerResponse) => { const server = http.createServer((request: http.IncomingMessage, response: http.ServerResponse) => {