cancel
Showing results for 
Search instead for 
Did you mean: 

DeclarativeWebScript can't check updated aspect until it runs asynchronously

jamilnour
Star Contributor
Star Contributor

Hello,

I have the following case:

From inside a DeclarativeWebScript (A) I have to wait (Thread.sleep) until a custom person aspect properties (of the active user) is updated by another DeclarativeWebScript (B). The Thread.sleep of A is terminated when a condition on the aspect properties (IndorsePeopleModel.PROP_INTESITRANSACTION) is successfully evaluated.

The problem I have is that even IndorsePeopleModel.PROP_INTESITRANSACTION is updated by B , A is never know and the sleep is never ended

It works only if A is called as ActionExecuter and asynchronously from a DeclarativeWebScript .

...
Action action = getServiceRegistry().getActionService().createAction("A", params);
action.setExecuteAsynchronously(true);
getServiceRegistry().getActionService().executeAction(action, docNodeRef);
...

But in this case I have a problem to know the status of the ActionExecuter

A:

...


long delta = 0;
        long startTime = System.currentTimeMillis();
        while (true)
        {
        try {
        long endTime = System.currentTimeMillis();
        delta = endTime - startTime;

        if (delta > 35000) break;

        JSONObject runJSONObject = (JSONObject) AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>()
        {
public JSONObject doWork() throws Exception
        {
        NodeRef userNodeRef = m_personService.getPerson(username);
        String transactionString = (String) getNodeService().getProperty(userNodeRef, IndorsePeopleModel.PROP_INTESITRANSACTION);
        logger.debug("transactionString = " + transactionString);
        JSONObject jsonTransaction = new JSONObject(transactionString);
        return jsonTransaction;
        }
        }, Constants.USER_ADMIN);

        approved = runJSONObject.get("approved").toString();
        logger.debug("approved = " + approved);


        if(jsonObject.get("approved").equals("1"))
        {
        setPin(jsonObject.get("pin").toString());
        break;
        }
        else{
        Thread.sleep(2000);
        continue;
        }


        } catch (Exception e) {
              throw new IllegalArgumentException("Error ", e);
           }
        }

...

B:

..

if (!getNodeService().hasAspect(userNodeRef, IndorsePeopleModel.ASPECT_PERSON)) {
    getNodeService().addAspect(userNodeRef, IndorsePeopleModel.ASPECT_PERSON, new HashMap<QName, Serializable>());
}
// add/replace the aspect  to person
//getNodeService().removeProperty(userNodeRef, IndorsePeopleModel.PROP_INTESITRANSACTION);
getNodeService().setProperty(userNodeRef, IndorsePeopleModel.PROP_INTESITRANSACTION, transactionString);
..

Thank you

Jamil

2 REPLIES 2

afaust
Legendary Innovator
Legendary Innovator

You should never use Thread sleeping / blocking to wait on disconnected process doing any kind of changes. Even using an asynchronous action does not guarantee this will work depending on the timing of the other web script invocation.

Why not simply have the client poll the web script until the expected state has been reached (or a timeout has been reached)? What component is triggering the call to B? If it is the same client, why are these calls not properly coordinated?

jamilnour
Star Contributor
Star Contributor

B is a webscript on the same server called by another server after some time (a rest hook callback url). I should wait until the B is called and update the aspect properties. So not the same client and can't coordinate unless by listening and waiting