1
- 'use strict' ;
2
-
3
- import httpProxy from 'http-proxy' ;
4
- import http from 'http' ;
5
- import { Database } from 'ueberdb2' ;
6
- import { checkAvailability } from './checkAvailability.ts'
7
1
import fs from 'fs'
2
+ import { start } from './runtime'
8
3
// load the settings
9
4
const loadSettings = ( ) => {
10
5
let settings ;
11
6
try {
12
- settings = fs . readFileSync ( 'settings.json' , 'utf8' ) ;
7
+ const settings_location = process . env [ "SETTINGS_FILE" ] || "settings.json"
8
+ settings = fs . readFileSync ( settings_location , 'utf8' ) ;
13
9
return JSON . parse ( settings ) ;
14
10
} catch ( e ) {
15
11
console . error ( 'Please create your own settings.json file' ) ;
@@ -19,138 +15,4 @@ const loadSettings = () => {
19
15
} ;
20
16
21
17
const settings = loadSettings ( ) ;
22
- console . debug ( settings ) ;
23
- if ( settings . dbType === 'dirty' ) console . error ( 'DirtyDB is not recommend for production' ) ;
24
-
25
- const backendIds = Object . keys ( settings . backends ) ;
26
-
27
- // An object of our proxy instances
28
- const proxies : { [ key : string ] : httpProxy < http . IncomingMessage , http . ServerResponse < http . IncomingMessage > > } = { } ;
29
-
30
- // Making availableBackend globally available.
31
- let availableBackends : {
32
- up : Array < string > ,
33
- available : Array < string > ,
34
- } ;
35
- ( async ( ) => {
36
- checkAvailability (
37
- settings . backends ,
38
- settings . checkInterval ,
39
- settings . maxPadsPerInstance ) ;
40
- } ) ( ) ;
41
- // And now grab them every X duration
42
- setInterval ( async ( ) => {
43
- availableBackends = await checkAvailability (
44
- settings . backends ,
45
- settings . checkInterval ,
46
- settings . maxPadsPerInstance ) ;
47
- } , settings . checkInterval ) ;
48
-
49
- // Creating our database connection
50
- const db = new Database ( settings . dbType , settings . dbSettings ) ;
51
-
52
- // Initiate the proxy routes to the backends
53
- const initiateRoute = ( backend : string , req :http . IncomingMessage , res : http . ServerResponse , socket :any , head :any ) => {
54
- if ( res ) {
55
- // console.log('backend: ', backend);
56
- if ( proxies [ backend ] ) {
57
- proxies [ backend ] . web ( req , res , { } , ( e ) => {
58
- console . error ( e ) ;
59
- } ) ;
60
- }
61
- }
62
- if ( socket && head ) {
63
- if ( proxies [ backend ] ) {
64
- proxies [ backend ] . ws ( req , socket , head , { } , ( e ) => {
65
- console . error ( e ) ;
66
- } ) ;
67
- }
68
- }
69
- } ;
70
-
71
- // Create dynamically assigned routes based on padIds and ensure that a route for
72
- // unique padIds are re-used and stuck to a backend -- padId <> backend association.
73
- const createRoute = ( padId : string | null , req : any , res :any , socket :any , head :any ) => {
74
- // If the route isn't for a specific padID IE it's for a static file
75
- // we can use any of the backends but now let's use the first :)
76
- if ( ! padId ) {
77
- const newBackend = availableBackends . available [
78
- Math . floor ( Math . random ( ) * availableBackends . available . length ) ] ;
79
- return initiateRoute ( newBackend , req , res , socket , head ) ;
80
- }
81
-
82
- // pad specific backend required, do we have a backend already?
83
- // @ts -ignore
84
- db . get ( `padId:${ padId } ` , ( e , r ) => {
85
- if ( r && r . backend ) {
86
- // console.log(`database hit: ${padId} <> ${r.backend}`);
87
- if ( ! availableBackends ) {
88
- return console . log ( 'Request made during startup.' ) ;
89
- }
90
- if ( availableBackends . up . indexOf ( r . backend ) !== - 1 ) {
91
- initiateRoute ( r . backend , req , res , socket , head ) ;
92
- } else {
93
- // not available.. actually it might be up but not available..
94
- console . log ( `hit backend not available: ${ padId } <> ${ r . backend } ` ) ;
95
- const newBackend = availableBackends . up [
96
- Math . floor ( Math . random ( ) * availableBackends . up . length ) ] ;
97
- // set and store a new backend
98
- db . set ( `padId:${ padId } ` , {
99
- backend : newBackend ,
100
- } ) ;
101
- console . log ( `creating new association: ${ padId } <> ${ newBackend } ` ) ;
102
- initiateRoute ( newBackend , req , res , socket , head ) ;
103
- }
104
- } else {
105
- // if no backend is stored for this pad, create a new connection
106
- console . log ( availableBackends ) ;
107
- const newBackend = availableBackends . available [
108
- Math . floor ( Math . random ( ) * availableBackends . available . length ) ] ;
109
- db . set ( `padId:${ padId } ` , {
110
- backend : newBackend ,
111
- } ) ;
112
- if ( ! availableBackends . available ) console . log ( 'no available backends!' ) ;
113
- console . log ( `database miss, initiating new association: ${ padId } <> ${ newBackend } ` ) ;
114
- initiateRoute ( newBackend , req , res , socket , head ) ;
115
- }
116
- } ) ;
117
- } ;
118
-
119
- db . init ( ) ;
120
-
121
- // Create the backends.
122
- for ( const backendId of backendIds ) {
123
- /* eslint-disable-next-line new-cap */
124
- proxies [ backendId ] = httpProxy . createProxyServer ( {
125
- target : {
126
- host : settings . backends [ backendId ] . host ,
127
- port : settings . backends [ backendId ] . port ,
128
- } ,
129
- } ) ;
130
- }
131
- // Create the routes for web traffic to those backends.
132
- const proxyServer = http . createServer ( ( req , res ) => {
133
- let padId : string | null = null ;
134
- if ( req . url ! . indexOf ( '/p/' ) !== - 1 ) {
135
- padId = req . url ! . split ( '/p/' ) [ 1 ] . split ( '?' ) [ 0 ] . split ( '/' ) [ 0 ] ;
136
- console . log ( `initial request to /p/${ padId } ` ) ;
137
- }
138
- if ( padId === null ) {
139
- const searchParams = new URLSearchParams ( req . url ) ;
140
- padId = searchParams . get ( '/socket.io/?padId' ) ;
141
- }
142
- createRoute ( padId as string , req , res , null , null ) ;
143
- } ) ;
144
-
145
- proxyServer . on ( 'error' , ( e ) => {
146
- console . log ( 'proxyserver error' , e ) ;
147
- } ) ;
148
-
149
- // Create a route for upgrade / websockets
150
- proxyServer . on ( 'upgrade' , ( req , socket , head ) => {
151
- const searchParams = new URLSearchParams ( req . url ) ;
152
- const padId = searchParams . get ( '/socket.io/?padId' ) ;
153
- createRoute ( padId , req , null , socket , head ) ;
154
- } ) ;
155
-
156
- proxyServer . listen ( settings . port ) ;
18
+ start ( settings ) ;
0 commit comments