Uploaded image for project: 'Solr'
  1. Solr
  2. SOLR-16282

Improve custom actions support of CoreAdminHandler

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Closed
    • Minor
    • Resolution: Fixed
    • main (10.0)
    • 9.1, main (10.0)
    • None
    • None

    Description

      Original CoreAdminHandler (org.apache.solr.handler.admin.CoreAdminHandler) has a support of custom actions by providing handleCustomAction method. It is intended for users who want to implement an additional actions (for example, for some instumental or statistical purposes). By default handleCustomAction method throws an exception implying user should subclass handler and provide its own handleCustomAction method implementation. But there are some structural problems.

      If we check how the CoreAdminHandler triggers the handleCustomAction method we will see that it is always runs in a sync way. Despite the fact that CoreAdminHandler has nice support of running the actions in an async way. Moreover, if user push the custom action request with an async parameter it will create TaskObject object and will place it to the tracking map occupying one slot and will never clean it up:

      org.apache.solr.handler.admin.CoreAdminHandler.handleRequestBody(SolrQueryRequest, SolrQueryResponse)

        @Override
        public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
            ...
            final String taskId = req.getParams().get(CommonAdminParams.ASYNC);
            final TaskObject taskObject = new TaskObject(taskId);
      
            if (taskId != null) {
              ...
              addTask(RUNNING, taskObject);
            }
      
            final String action = req.getParams().get(ACTION, STATUS.toString()).toLowerCase(Locale.ROOT);
            CoreAdminOperation op = opMap.get(action);
            if (op == null) {
              handleCustomAction(req, rsp);
              return;
            }
            
            final CallInfo callInfo = new CallInfo(this, req, rsp, op);
            ...
            if (taskId == null) {
              callInfo.call();
            } else {
              try {
                ...
                parallelExecutor.execute(
                    () -> {
                      boolean exceptionCaught = false;
                      try {
                        callInfo.call();
                        taskObject.setRspObject(callInfo.rsp);
                        taskObject.setOperationRspObject(callInfo.rsp);
                      } catch (Exception e) {
                        exceptionCaught = true;
                        taskObject.setRspObjectFromException(e);
                      } finally {
                        removeTask("running", taskObject.taskId);
                        if (exceptionCaught) {
                          addTask("failed", taskObject, true);
                        } else {
                          addTask("completed", taskObject, true);
                        }
                      }
                    });
              } finally {
                ...
              }
            }
            ...
        } 

      As we can see, the call to the handleRequestBody is just a call to the custom block of the code that is not weaved nicely to the overall worflow. I suggest to update the logic to not just call custom block of the code, but instead to force it to provide a CoreAdminOp instance, that would be used in the further execution as a regular operation extracterd from the opMap. Like this:

       

            ...
            final String action = req.getParams().get(ACTION, STATUS.toString()).toLowerCase(Locale.ROOT);
            CoreAdminOp op = opMap.get(action);
            if (op == null) {
              op = getCustomOperation(action);
            }
            ...
      

       

      This way the custom actions can be easily integrated in the general worflow with minimal efforts. In result we will get:

      • support of an async custom actions
      • using of the standard CoreAdminOp and CallInfo structures
      • more clean code

      Attachments

        Issue Links

          Activity

            People

              cpoerschke Christine Poerschke
              abeleshev Artem Abeleshev
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0h
                  0h
                  Logged:
                  Time Spent - 7h 10m
                  7h 10m