1
0
mirror of https://github.com/bigchaindb/js-bigchaindb-driver.git synced 2024-06-26 03:06:42 +02:00
js-bigchaindb-driver/src/transport.js

74 lines
2.3 KiB
JavaScript
Raw Normal View History

2018-08-23 17:14:59 +02:00
// 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
2018-08-22 10:10:09 +02:00
import Request from './request'
2018-08-28 14:09:26 +02:00
/**
*
* @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).
*/
2018-08-22 10:10:09 +02:00
export default class Transport {
2018-08-28 14:27:53 +02:00
constructor(nodes, timeout) {
2018-08-22 10:10:09 +02:00
this.connectionPool = []
this.timeout = timeout
2018-08-28 14:09:26 +02:00
// the maximum backoff time is 10 seconds
2018-08-29 16:39:15 +02:00
this.maxBackoffTime = timeout ? timeout / 2 : 10000
2018-08-22 10:10:09 +02:00
nodes.forEach(node => {
2018-08-28 14:27:53 +02:00
this.connectionPool.push(new Request(node))
2018-08-22 10:10:09 +02:00
})
}
2018-08-28 14:09:26 +02:00
// Select the connection with the earliest backoff time, in case of a tie,
// prefer the one with the smaller list index
2018-08-22 10:10:09 +02:00
pickConnection() {
let connection = this.connectionPool[0]
2018-08-23 17:14:59 +02:00
2018-08-22 10:10:09 +02:00
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) {
2018-08-23 17:14:59 +02:00
let response
let connection
2018-08-28 14:09:26 +02:00
// A new request will be executed until there is a valid response or timeout < 0
while (this.timeout >= 0) {
2018-08-23 17:14:59 +02:00
connection = this.pickConnection()
2018-08-22 10:10:09 +02:00
// Date in milliseconds
const startTime = Date.now()
try {
2018-08-23 17:14:59 +02:00
// eslint-disable-next-line no-await-in-loop
response = await connection.request(
2018-08-22 10:10:09 +02:00
path,
headers,
2018-08-28 14:09:26 +02:00
this.timeout,
this.maxBackoffTime
2018-08-22 10:10:09 +02:00
)
const elapsed = Date.now() - startTime
if (connection.backoffTime > 0 && this.timeout > 0) {
2018-08-28 14:09:26 +02:00
this.timeout -= elapsed
2018-08-23 17:14:59 +02:00
} else {
2018-08-28 14:09:26 +02:00
// No connection error, the response is valid
2018-08-23 17:14:59 +02:00
return response
}
} catch (err) {
throw err
2018-08-22 10:10:09 +02:00
}
}
2018-08-23 17:14:59 +02:00
const errorObject = {
2018-08-28 14:09:26 +02:00
message: 'TimeoutError',
2018-08-23 17:14:59 +02:00
}
2018-08-29 16:39:15 +02:00
throw errorObject
2018-08-22 10:10:09 +02:00
}
}