(九) CompletableFuture使用

需求

需要一个同步返回结果,可是同步返回结果依赖另一个异步操作.希望能把异步操作封装成同步动作.这个封装工具就能用大名鼎鼎的
CompletableFuture

案例

/**
	获得的同步返回结果有两种信息,
	一种是需要等待第三方callback有用信息的(async),
	另一种直接返回有用信息(sync).

	future 里面通过 complete 方法放入一个 value, 
	再通过 get 方法将其取出
**/

 //创建一个Future
 messageHandler.buildFuture(accountValidationRequest.orderId)
 
 return try {
 
            when (response) {
            
            	//同步,直接映射成需要的结果并返回
                sync -> Util.mapToBankAccountProbingResponse(request, accountValidationResponse)
                
                //异步,映射一个未来的结果
                async ->Util.mapToBankAccountProbingResponse(request, messageHandler.waitCallBack(response.orderId!!)
            }

        } catch (e: TimeoutException) {
            logger.info("has not receive callback from chinapnr in {} sec,call resultCheck interface", WAITINGTTL)
            val resultCheckRequest = ResultCheckRequest(accountValidationRequest.orderId, accountValidationResponse.seqId!!)
            Util.mapToBankAccountProbingResponse(request, accountValidationProxy.resultCheck(resultCheckRequest))
        } finally {
        
        	//最后,把Futuare移除
            messageHandler.removeFuture(accountValidationRequest.orderId)
        }
MessageHandler
@Component
class MessageHandler {

    @Value("\${awx.chinapnr.wait_time}")
    private var timeOut: Long = 5
    private var logger = LoggerFactory.getLogger(MessageHandler::class.java)

	//定义一个ConpletableFutlre 的 ConcurrentHashMap,在创建Future和delete Future 时能保证不会受到重复请求的干扰
	定义futuare中value的类型为AccountValidationResponse
    var mapper = ConcurrentHashMap<String, CompletableFuture<AccountValidationResponse>>()

	//创建future方法
    fun buildFuture(orderId: String) {
        mapper[orderId] = CompletableFuture()
    }

	//获取future方法,定义了timeout,超时直接报timeout异常,返回
    fun waitCallBack(orderId: String): AccountValidationResponse? {
        var future = mapper[orderId]
        //取出future的value
        return future!!.get(timeOut, TimeUnit.SECONDS)
    }

	//futureComplete条件
    fun sendCallBackMessage(orderId: String, accountValidationResponse: AccountValidationResponse) {
        var future = mapper[orderId]
        //通过complete设置future的value
        future?.complete(accountValidationResponse)
                ?: logger.error("receive an unexpected callback from chinapnr, orderId: {}", orderId)
    }

	//删除future
    fun removeFuture(orderId: String) = mapper.remove(orderId)

}
FutureComplete条件: 在timeout前收到第三方的callback
@RestController
@RequestMapping("/v1")
class CallBackHandler {

    private var logger = LoggerFactory.getLogger(CallBackHandler::class.java)
    @Autowired
    private lateinit var messageHandler: MessageHandler


    @RequestMapping(produces = ["application/x-www-form-urlencoded"], value = "/infovalidation", method = [RequestMethod.POST, RequestMethod.GET])
    fun callBack(request: CallBackRequest): String {
        logger.info("callback request from chinapnr: " + Codecs.objToJsonString(request))

        var seqId = request.seq_id
        var accountValidationResponse = mapToAccountValidationResponse(request)

        messageHandler.sendCallBackMessage(request.order_id, accountValidationResponse)


        return "RECV_ORD_ID_$seqId"
    }

    private fun mapToAccountValidationResponse(request: CallBackRequest): AccountValidationResponse {
        return AccountValidationResponse(
                request.return_code!!,
                request.return_message,
                request.resp_code,
                request.resp_info,
                request.seq_id,
                request.order_id,
                ""
        )
    }
}

扩展阅读

https://www.jianshu.com/p/6f3ee90ab7d3

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值