FISCO-BCOS / web3sdk

java sdk for FISCO BCOS(deprecated, please use FISCO-BCOS/java-sdk)
Apache License 2.0
117 stars 86 forks source link

EventLog事件callback在多线程时次序不一致的问题 #714

Open CodingCattwo opened 4 years ago

CodingCattwo commented 4 years ago

在获取历史区块中event时

代码如下:

即status=1的callback比status=0的callback先到达,导致未获取到完整的eventlog list,但是由于status==1导致我的CompletableFuture提前结束了。

private CompletableFuture<List<LogResult>> future;
private List<LogResult> finalList;
 @Override
    public void onPushEventLog(int status, List<LogResult> logs) {
        logger.info(
            "SyncEventLogCallback onPushEventLog params: {}, status: {}, logs: {}",
            getFilter().getParams(), status, logs);
        // status == 0 push not finish,
        if (status == 0) {
            // add in resultList
            if (logs != null) {
                finalList.addAll(logs);
            }
        } else if (status == 1){
            if (logs != null) {
                finalList.addAll(logs);
            }
             // avoid last log callback(status=0) coming after success callback(status=1)
//            try {
//                Thread.sleep(100);
//            } catch (InterruptedException e) {
//                logger.error("sleep 100ms interrupted:{}", JsonUtils.objToString(e.getStackTrace()));
//            }
            logger.info(
                "SyncEventLogCallback push finished status: {}, finalList size:{}",
                status, finalList.size());
            future.complete(finalList);
        } else {
            // not 0, not 1, error
            logger.error("SyncEventLogCallback onPushEventLog error!");
            future.complete(finalList);
        }
    }

日志如下: image

可以看到同一线程时,存储log的finalList size为1,但是不同线程时,finalList size为0就结束了。导致这两次过滤的入参相同,但是获取的事件列表不一致

临时解决方法:在status=1时,加上Thread.sleep(100);,让CompletableFuture稍晚结束,即可获取最后一条的log callback