mirror of
https://github.com/bigchaindb/js-bigchaindb-driver.git
synced 2024-06-17 01:53:18 +02:00
74 lines
2.3 KiB
JavaScript
74 lines
2.3 KiB
JavaScript
// Copyright BigchainDB GmbH and BigchainDB contributors
|
|
// SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
|
|
// Code is Apache-2.0 and docs are CC-BY-4.0
|
|
|
|
import Request from './request'
|
|
|
|
|
|
/**
|
|
*
|
|
* @private
|
|
* If initialized with ``>1`` nodes, the driver will send successive
|
|
* requests to different nodes in a round-robin fashion (this will be
|
|
* customizable in the future).
|
|
*/
|
|
|
|
|
|
export default class Transport {
|
|
constructor(nodes, timeout) {
|
|
this.connectionPool = []
|
|
this.timeout = timeout
|
|
// the maximum backoff time is 10 seconds
|
|
this.maxBackoffTime = timeout ? timeout / 2 : 10000
|
|
nodes.forEach(node => {
|
|
this.connectionPool.push(new Request(node))
|
|
})
|
|
}
|
|
|
|
// Select the connection with the earliest backoff time, in case of a tie,
|
|
// prefer the one with the smaller list index
|
|
pickConnection() {
|
|
let connection = this.connectionPool[0]
|
|
|
|
this.connectionPool.forEach(conn => {
|
|
// 0 the lowest value is the time for Thu Jan 01 1970 01:00:00 GMT+0100 (CET)
|
|
conn.backoffTime = conn.backoffTime ? conn.backoffTime : 0
|
|
connection = (conn.backoffTime < connection.backoffTime) ? conn : connection
|
|
})
|
|
return connection
|
|
}
|
|
|
|
async forwardRequest(path, headers) {
|
|
let response
|
|
let connection
|
|
// A new request will be executed until there is a valid response or timeout < 0
|
|
while (this.timeout >= 0) {
|
|
connection = this.pickConnection()
|
|
// Date in milliseconds
|
|
const startTime = Date.now()
|
|
try {
|
|
// eslint-disable-next-line no-await-in-loop
|
|
response = await connection.request(
|
|
path,
|
|
headers,
|
|
this.timeout,
|
|
this.maxBackoffTime
|
|
)
|
|
const elapsed = Date.now() - startTime
|
|
if (connection.backoffTime > 0 && this.timeout > 0) {
|
|
this.timeout -= elapsed
|
|
} else {
|
|
// No connection error, the response is valid
|
|
return response
|
|
}
|
|
} catch (err) {
|
|
throw err
|
|
}
|
|
}
|
|
const errorObject = {
|
|
message: 'TimeoutError',
|
|
}
|
|
throw errorObject
|
|
}
|
|
}
|