Bug #2774

Participant deactivation is blocking forever if the interrupted exception is not recovered.

Added by M. Pohling 11 months ago. Updated 11 months ago.

Status:ResolvedStart date:10/17/2018
Priority:NormalDue date:
Assignee:-% Done:

100%

Category:Java
Target version:rsb-0.18

Description

error blocking forever when the interrupted exception is not recovered.

setup spread configured via global config file and locally started.

test code

public static void main(String[] args) {
    LocalServer server = Factory.getInstance().createLocalServer("/test/scope");
    RemoteServer remote = Factory.getInstance().createRemoteServer("/test/scope");

    try {
        server.addMethod("mymethod", new Callback() {
            @Override
            public Event internalInvoke(Event request) throws UserCodeException {
                System.out.println("process task");
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException ex) {
                    // Thread.currentThread().interrupt();
                    System.out.println("interrupt task");
                    throw new UserCodeException(ex);
                }
                return request;
            }
        });
    } catch (RSBException e) {
        e.printStackTrace();
    }

    System.out.println("activate");
    try {
        server.activate();
    } catch (RSBException e) {
        e.printStackTrace();
    }
    try {
        remote.activate();
    } catch (RSBException e) {
        e.printStackTrace();
    }

    System.out.println("trigger server task");
    try {
        remote.callAsync("mymethod");
    } catch (RSBException e) {
        e.printStackTrace();
    }
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("deactivate");
    try {
        server.deactivate();
    } catch (RSBException | InterruptedException e) {
        e.printStackTrace();
    }
    try {
        remote.deactivate();
    } catch (RSBException | InterruptedException e) {
        e.printStackTrace();
    }
}

output

activate
trigger server task
process task
deactivate
interrupt task
Oct 17, 2018 2:27:34 PM rsb.patterns.LocalMethod internalNotify
WARNING: Exception during method invocation in participant: /test/scope/mymethod/. Exception message: java.lang.InterruptedException: sleep interrupted

// until than its blocking forever when the interrupted exception is not recovered.

Associated revisions

Revision 7dcfa051
Added by J. Wienke 11 months ago

Backport: Make handlers interruptible

Let handlers and callbacks throw InterruptedExceptions to ensure that
participants can be deactivated while a call to handler is running.

fixes #2774

(cherry picked from commit 56db1280e805210314a0defa3300e2512babaaea)

Revision 180525f9
Added by J. Wienke 11 months ago

Backport: Make handlers interruptible

Let handlers and callbacks throw InterruptedExceptions to ensure that
participants can be deactivated while a call to handler is running.

refs #2774

(cherry picked from commit 56db1280e805210314a0defa3300e2512babaaea)

Revision 20dfdfc8
Added by J. Wienke 11 months ago

Backport: Make handlers interruptible

Let handlers and callbacks throw InterruptedExceptions to ensure that
participants can be deactivated while a call to handler is running.

refs #2774

(cherry picked from commit 56db1280e805210314a0defa3300e2512babaaea)

History

#1 Updated by J. Wienke 11 months ago

I don't see who interrupts whom at which time in the test code. When should the interruption take place?

#2 Updated by M. Pohling 11 months ago

Its an user code stability issue.
Just execute the example code and you will see that the deactivation method blocks forever.
If the interrupted exception is packed into an UserCodeException:

} catch (InterruptedException ex) {
    // Thread.currentThread().interrupt();
    System.out.println("interrupt task");
    throw new UserCodeException(ex);
}

and the interruption is not recovered by the usercode like this:

Thread.currentThread().interrupt();

You should make sure that the

server.deactivate();

remote.deactivate();

are never blocking because of any still processing or already canceled tasks.

#3 Updated by J. Wienke 11 months ago

Actually, I don't see how we should solve this without client help. We need interruption to enable a fast deactivation of participants and their internal threads. But if the client code running inside this thread isn't cooperative and swallows the interrupted state, we have no chance to notice it. Adding a second flag in addition to the interrupted flag sounds awkward.

#4 Updated by J. Wienke 11 months ago

  • Status changed from New to Resolved
  • % Done changed from 0 to 100

Also available in: Atom PDF