我一直在研究这个数据收集模块,该模块应该从不同的比特币市场获取数据并标准化所有接收的数据,以便将其插入到mongodb数据库中供以后使用。 (该模块在节点4.3.x中编写)
我遇到的问题是我需要在数据库中如何表示数据的一致性。因此,每当请求超时,而不是捕获get请求并记录错误,我想解决'0'。 此外,收到的数据包含需要按顺序切割的交易。这需要发生,以便可以正确地切割交易,因此数据不会被写入两次。 为此,我实现了两个队列:
1:TimestampQueue - 保存时间戳。 [0]中的时间戳是下一个预期响应
2:objectQueue - 保存收到的回复
=>只要objectQueue [0]中的对象等于timestampQueue [0] =>中的时间戳。做数据操作并插入数据库。
问题在于应该捕获超时的axios.get请求不能始终如一地执行此操作。
它发生在随机时间帧之后,但平均而言,队列在2小时后就会卡住。
为了让事情更加清晰,一些重要的代码片段: httpclient发出axios请求:
get(url) {
return this.instance.get(url) //instance just defined a timeout. Nothing special
.then(response => {
return response.data;
})
.catch(error => {
throw error; //THIS SEEMINGLY DOESN'T GET EXECUTED IN THE DESCRIBED CASE
});
}
现在解决请求的marketHandler:
getMethodFromMarket(method, market, timestamp){
if(this.markets[market]){
if(this.markets[market].methods[method]) {
var url = this.markets[market].methods[method];
let result = {};
result[method] = {};
result[method][market] = {};
return this.client.get(url)
.then(data => {
result[method][market] = data;
log.debug("Successfully received " + method + " for " + market + " : " + timestamp);
return result;
})
.catch(err => {
result[method][market] = 0;
log.error(new Error("Failed to get " + method + " for " + market + ": " + timestamp));
log.error(err);
return result;
});
} else{
return Promise.reject(new Error(method + " not available for " + market));
}
} else {
return Promise.reject(new Error("Market not specified in config"));
}
}
为所有已定义市场(针对一种方法)发出请求并将它们连接到一个对象的代码:
//returns promise to get *method* from all markets specified in
//config.json
getAllMarkets(method, timestamp){
let getMarketsPromises = [];
let result = {};
result[method] = {};
Object.keys(this.markets).forEach(market => {
result[method][market] = {};
getMarketsPromises.push(this.getMethodFromMarket(method, market, timestamp));
});
return Promise.all(getMarketsPromises)
.then(results => {
for(let i = 0; i < results.length; i++){
let market = Object.keys(results[i][method])[0];
result[method][market] = results[i][method][market];
}
log.debug("Got all markets for " + method + " for " + timestamp);
return result;
})
}
生成所有方法和市场请求的代码,并将它们连接到最终对象中,该对象从不同的模块进行操作并插入到数据库中:
//returns promise to get trades and depths from markets specified in
//config.json
getEverything(timestamp){
let getMethodPromises = [];
let result = {timestamp};
this.methods.forEach(method => {
result[method] = {};
getMethodPromises.push(this.getAllMarkets(method, timestamp))
});
return Promise.all(getMethodPromises)
.then(results =>{
for(let i = 0; i < results.length; i++){
let method = Object.keys(results[i])[0];
result[method] = results[i][method];
}
log.debug("Got everything for " + timestamp);
return result;
})
}
我测试了整个过程,没有任何数据操作。只有那些功能并将其插入数据库。
实施2个队列:
//handles the incoming responses from markets and sorts
//them according to their timestamp
queueResponse(marketInfo){
this.marketInfoQueue.push(marketInfo);
this.marketInfoQueue.sort(function(a, b){
return a.timestamp - b.timestamp;
})
}
//returns queued Responses in order of timestamps.
getQueuedResponses(){
var i = 0;
var results = [];
log.debug("TimestampQueue: "+ this.timestampQueue[0] + " | objectQueue: " + this.marketInfoQueue[0].timestamp);
while(this.marketInfoQueue[i] && this.timestampQueue[i] == this.marketInfoQueue[i].timestamp){
results.push(this.marketInfoQueue.shift());
this.timestampQueue.shift();
i++;
}
return results;
}
//pushes new timestamp into timestampQueue to keep
//incoming responses in order
queueTimestamp(timestamp){
this.timestampQueue.push(timestamp);
}
我一直试图解决这个问题超过3个星期了,我绝对是一无所知。
TLDR:Axios get请求无法解析或拒绝。即使在httpClient模块中使用的实例中定义了5000ms的超时。