Work Executor Sample的异步Spring REST调用

时间:2016-07-26 07:23:30

标签: spring rest

我正在开发工作执行器软件。到目前为止,这是按照以下方式设计的:

  1. 客户端将调用URL,该URL将调用Spring REST控制器方法
  2. REST控制器获取一个bean“WorkAcceptor”,它被配置为“prototype”。
  3. 类“WorkAcceptor”创建一个名为“WorkQInserter”的bean对象,并将请求传递给“WorkQInserter”的“enqueueTasks()”。在调用enqueueTasks()之后,它会将生成的工作ID发送给客户端。
  4. 在Oracle对象上调用方法“enqueueTasks()”,该对象在Oracle AQ中存储请求
  5. 单个后台线程“WorkExecutor”连续运行,从AQ弹出请求并将请求转发给另一个单件对象“WorkExecutor”进行处理
  6. “WorkExecutor”以reuested的形式执行工作并将结果存储在Oracle DB中,完成整个过程大约需要30-40秒
  7. 请注意,WorkExecutor从FIFO Q获取请求并执行相同的操作并存储在DB中。 客户端必须通过调用不同的REST(用于检索工作状态)来检查以后的工作状态(使用步骤#3中收到的引用工作项)。

    我在异步方法调用方面几乎没有任何知识。 我想知道对#1中的REST控制器或任何其他相关类进行哪些更改以使REST调用异步?这样客户端异步调用REST,获得接受响应,在AQ中推送请求,“WorkExecutor”从AQ弹出请求并执行工作,存储在DB中并在客户端上回调成功/失败。

    请注意我的代码段。 bean在spring配置bean xml文件中配置。

    任何有关样品的想法都将受到高度赞赏。提前谢谢,请原谅我的长篇文章。

    REST控制器

    @RestController
    public class WorkExecutorRESTController {
    
        @RequestMapping(value = "/workexecutor/{workdetails}", method = RequestMethod.GET)
        public ResponseEntity<Integer> executeWork( @PathVariable String workdetails ) 
        {
            WorkAcceptor l_WorkAcceptor = WorkerBeanFactory.getBeanForId("WorkAcceptor"); //configured as prototype bean
            Integer result = l_WorkAcceptor.sendWork(workdetails);
            return new ResponseEntity<Integer>(result,HttpStatus.OK);
        }
    

    WorkAcceptor类

    public class WorkAcceptor {
    
        public Integer sendWork(String workdetails)
        {
            WorkQInserter l_WorkQInserter = WorkerBeanFactory.getBeanForId("WorkQInserter"); //configured as prototype bean
    
            // Here generate the work id
    
            if(l_WorkQInserter.enqueueTasks(workdetails, workid) == SUCCESSFUL)
            {
                return workid; //this goes back to client as reference id
            }
            else
                return -1;
        }
    }
    

    WorkQInserter类

    public class WorkQInserter {
    
        public Integer WorkQInserter(String workdetails, Integer workid)
        {
            //PUSH THE DATA IN ORACLE AQ
            //RETURN SUCCESS OR FAILURE
        }
    }
    

    WorkExecutor类

    //This class is configured as singleton in bean xml. During initialization it runs a dedicated thread
    //which periodically pops out request from the AQ and process
    
    public class WorkExecutor {
    
        public Integer execute()
        {
            //POPS OUT THE REQUEST FROM ORACLE AQ
            //EXECUTE WORK
            //RETURN SUCCESS OR FAILURE
        }
    }
    

1 个答案:

答案 0 :(得分:0)

总结上述评论:

  • 所有请求退出的已配置回调终结点。
  • 不得调用回调事务
  • 回调可能会丢失。

工作由 WorkExecutor 异步完成。客户端立即获得 workId 的句柄,如果回调丢失,它可用于查询状态。 WorkExectutor 通过已配置的回调端点通知客户端有关工作的最终状态。

即。 WorkExecutor 类似于:

public class WorkExecutor {

    public Integer execute()
    {
        //POPS OUT THE REQUEST FROM ORACLE AQ
        //EXECUTE WORK

        // invoke client callback passing the workId
        // workId should be available form the queue
        // callback endpoint is static / configurable fix for all requests 
        // successStatus is the status whether the request was fulfilled successfully or even not.
        notifyClient(workId, successStatus);
    }
}

你的 RestController

@RestController
public class WorkExecutorRESTController {

    @RequestMapping(value = "/workexecutor/{workdetails}", method = RequestMethod.GET)
    public ResponseEntity<Integer> executeWork( @PathVariable String workdetails ) 
    {
        WorkAcceptor l_WorkAcceptor = WorkerBeanFactory.getBeanForId("WorkAcceptor"); //configured as prototype bean
        Integer result = l_WorkAcceptor.sendWork(workdetails);
        return new ResponseEntity<Integer>(result,HttpStatus.ACCEPTED); // accepted rather than 200 / OK
    }
}

无需使REST服务本身异步。