[ 
https://issues.apache.org/jira/browse/CAMEL-7490?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Ajay Kapoor updated CAMEL-7490:
-------------------------------

    Description: 
My application needs to modify the redelivery delay at runtime, thereby 
overriding the values set by the application during configuration /loading time.
The Redelivery delay for subsequent retries will have varied retry intervals 
and it needs to be done asynchronously. As of the current implementation, this 
is possible only in synchronous mode where by the thread handling the message 
on a route sleeps for specified amount time and uses the 
Exchange.REDELIVERY_DELAY header to populate the delay values for each 
reattempt.

Issue 1:
In asynchronous mode, the Exchange.REDELIVERY_DELAY is used only in the first 
attempt and the same value is used in subsequent attempts. 

Issue 2:
There is no mechanism to set the delayPattern value if set for Redelivery 
Policy at runtime. Need to have some mechanism where the DELAY_PATTERN can be 
passed via Exchange at runtime such that it gets used for retries 
asynchronously.

Possible Fix::
-----------------
Issue-1:
 org.apache.camel.processor:: RedeliveryErrorHandler
---------------------------------------------------------------------
In the method (processAsyncErrorHandler) below, the code calls 
calculateRedeliveryDelay() API for calculating the redelivery delay which is 
wrong.  It should be calling the wrapper API - determineRedeliveryDelay() in 
its place which will allow the usage of Exchange.REDELIVERY_DELAY being passed 
in the headers. That way, it will allow the user to have the complete 
asynchronous behavior based on the values being passed to the CAMEL at runtime.

The following code points to the bug exists::

public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport 
implements AsyncProcessor, ShutdownPrepared {
...........
    private class AsyncRedeliveryTask implements Callable<Boolean> {
..............
    protected void processAsyncErrorHandler(final Exchange exchange, final 
AsyncCallback callback, final RedeliveryData data) {
..............

        if (data.redeliveryCounter > 0) {
            // we are doing a redelivery then a thread pool must be configured 
(see the doStart method)
            ObjectHelper.notNull(executorService, "Redelivery is enabled but 
ExecutorService has not been configured.", this);

            // let the RedeliverTask be the logic which tries to redeliver the 
Exchange which we can used a scheduler to
            // have it being executed in the future, or immediately
            // Note: the data.redeliverFromSync should be kept as is, in case 
it was enabled previously
            // to ensure the callback will continue routing from where we left
            AsyncRedeliveryTask task = new AsyncRedeliveryTask(exchange, 
callback, data);

            // calculate the redelivery delay
            data.redeliveryDelay = 
data.currentRedeliveryPolicy.calculateRedeliveryDelay(data.redeliveryDelay, 
data.redeliveryCounter);
            if (data.redeliveryDelay > 0) {
                // schedule the redelivery task
                if (log.isTraceEnabled()) {
                    log.trace("Scheduling redelivery task to run in {} millis 
for exchangeId: {}", data.redeliveryDelay, exchange.getExchangeId());
                }
                executorService.schedule(task, data.redeliveryDelay, 
TimeUnit.MILLISECONDS);
            } else {
                // execute the task immediately
                executorService.submit(task);
            }
        }
    }

}

}


  was:
My application needs to modify the redelivery delay at runtime, thereby 
overriding the values set by the application during configuration /loading time.
The Redelivery delay for subsequent retries will have varied retry intervals 
and it needs to be done asynchronously. As of the current implementation, this 
is possible only in synchronous mode where by the thread handling the message 
on a route sleeps for specified amount time and uses the 
Exchange.REDELIVERY_DELAY header to populate the delay values for each 
reattempt.
Issue 1:
In asynchronous mode, the Exchange.REDELIVERY_DELAY is used only in the first 
attempt and the same value is used in subsequent attempts. 

Issue 2:
There is mechanism to set the delayPattern value at runtime.

Possible Fix::
 org.apache.camel.processor:: RedeliveryErrorHandler
---------------------------------------------------------------------
In the method (processAsyncErrorHandler) below, the code calls 
calculeRedeliveryData() API for calculating the redelivery delay which is 
wrong.  It should be calling the wrapper API - determineRedeliveryDelay() in 
its place which will allow the usage of Exchange.REDELIVERY_DELAY being passed 
in the headers. That way, it will allow the user to have the complete 
asynchronous behavior based on the values being passed to the CAMEL at runtime.

The following code points to the bug exists::

public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport 
implements AsyncProcessor, ShutdownPrepared {
...........
    private class AsyncRedeliveryTask implements Callable<Boolean> {
..............
    protected void processAsyncErrorHandler(final Exchange exchange, final 
AsyncCallback callback, final RedeliveryData data) {
..............

        if (data.redeliveryCounter > 0) {
            // we are doing a redelivery then a thread pool must be configured 
(see the doStart method)
            ObjectHelper.notNull(executorService, "Redelivery is enabled but 
ExecutorService has not been configured.", this);

            // let the RedeliverTask be the logic which tries to redeliver the 
Exchange which we can used a scheduler to
            // have it being executed in the future, or immediately
            // Note: the data.redeliverFromSync should be kept as is, in case 
it was enabled previously
            // to ensure the callback will continue routing from where we left
            AsyncRedeliveryTask task = new AsyncRedeliveryTask(exchange, 
callback, data);

            // calculate the redelivery delay
            data.redeliveryDelay = 
data.currentRedeliveryPolicy.calculateRedeliveryDelay(data.redeliveryDelay, 
data.redeliveryCounter);
            if (data.redeliveryDelay > 0) {
                // schedule the redelivery task
                if (log.isTraceEnabled()) {
                    log.trace("Scheduling redelivery task to run in {} millis 
for exchangeId: {}", data.redeliveryDelay, exchange.getExchangeId());
                }
                executorService.schedule(task, data.redeliveryDelay, 
TimeUnit.MILLISECONDS);
            } else {
                // execute the task immediately
                executorService.submit(task);
            }
        }
    }

}

}



> Redelivery delay cannot be modified in asynchronous mode for multiple retries 
> with different redelivery intervals for each retry specified in 
> Exchange.RELEIVERY_HEADER parameter.
> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-7490
>                 URL: https://issues.apache.org/jira/browse/CAMEL-7490
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-core
>    Affects Versions: 2.12.2
>         Environment: Linux - JBOSS
>            Reporter: Ajay Kapoor
>              Labels: Delay, RUntime, asynchrnous, in, mode, modification, 
> redelivery
>             Fix For: 2.12.4
>
>   Original Estimate: 96h
>  Remaining Estimate: 96h
>
> My application needs to modify the redelivery delay at runtime, thereby 
> overriding the values set by the application during configuration /loading 
> time.
> The Redelivery delay for subsequent retries will have varied retry intervals 
> and it needs to be done asynchronously. As of the current implementation, 
> this is possible only in synchronous mode where by the thread handling the 
> message on a route sleeps for specified amount time and uses the 
> Exchange.REDELIVERY_DELAY header to populate the delay values for each 
> reattempt.
> Issue 1:
> In asynchronous mode, the Exchange.REDELIVERY_DELAY is used only in the first 
> attempt and the same value is used in subsequent attempts. 
> Issue 2:
> There is no mechanism to set the delayPattern value if set for Redelivery 
> Policy at runtime. Need to have some mechanism where the DELAY_PATTERN can be 
> passed via Exchange at runtime such that it gets used for retries 
> asynchronously.
> Possible Fix::
> -----------------
> Issue-1:
>  org.apache.camel.processor:: RedeliveryErrorHandler
> ---------------------------------------------------------------------
> In the method (processAsyncErrorHandler) below, the code calls 
> calculateRedeliveryDelay() API for calculating the redelivery delay which is 
> wrong.  It should be calling the wrapper API - determineRedeliveryDelay() in 
> its place which will allow the usage of Exchange.REDELIVERY_DELAY being 
> passed in the headers. That way, it will allow the user to have the complete 
> asynchronous behavior based on the values being passed to the CAMEL at 
> runtime.
> The following code points to the bug exists::
> public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport 
> implements AsyncProcessor, ShutdownPrepared {
> ...........
>     private class AsyncRedeliveryTask implements Callable<Boolean> {
> ..............
>     protected void processAsyncErrorHandler(final Exchange exchange, final 
> AsyncCallback callback, final RedeliveryData data) {
> ..............
>         if (data.redeliveryCounter > 0) {
>             // we are doing a redelivery then a thread pool must be 
> configured (see the doStart method)
>             ObjectHelper.notNull(executorService, "Redelivery is enabled but 
> ExecutorService has not been configured.", this);
>             // let the RedeliverTask be the logic which tries to redeliver 
> the Exchange which we can used a scheduler to
>             // have it being executed in the future, or immediately
>             // Note: the data.redeliverFromSync should be kept as is, in case 
> it was enabled previously
>             // to ensure the callback will continue routing from where we left
>             AsyncRedeliveryTask task = new AsyncRedeliveryTask(exchange, 
> callback, data);
>             // calculate the redelivery delay
>             data.redeliveryDelay = 
> data.currentRedeliveryPolicy.calculateRedeliveryDelay(data.redeliveryDelay, 
> data.redeliveryCounter);
>             if (data.redeliveryDelay > 0) {
>                 // schedule the redelivery task
>                 if (log.isTraceEnabled()) {
>                     log.trace("Scheduling redelivery task to run in {} millis 
> for exchangeId: {}", data.redeliveryDelay, exchange.getExchangeId());
>                 }
>                 executorService.schedule(task, data.redeliveryDelay, 
> TimeUnit.MILLISECONDS);
>             } else {
>                 // execute the task immediately
>                 executorService.submit(task);
>             }
>         }
>     }
> }
> }



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Reply via email to