Business Logic called multiple times, completes only once

I have Business Logic in place that registers a new Backendless user when called. This function works fine when called once, but when called multiple times (for example, within a loop) it only completes once, leaving one user registered and the others ignored.

Is there a limit or other reason that would prevent Business Logic functions from being called in rapid succession? I am calling the function via REST from Parse cloud code, the purpose is to batch create new Backendless users as they are created in Parse.

I have validated that the API does get called several times via the analytics section of the Backendless console, which shows the number of API calls.

Any help or suggestions would be appreciated.

Is your code implemented as a hosted service or custom event handler?

Hosted Service.

Is the service called (from Parse’s Cloud Code) in the rapid fire OR inside of the service you call some backendless API in a loop?

The service is called from Parse’s Cloud Code rapid fire.

The sequence:
-Parse Cloud code job kicks off on a schedule.
-A collection of new Parse users is identified (let’s say 20 users).
-From Parse Cloud code, I loop through all 20 users, calling the Backendless hosted service each time to register the user.

  • Parse Cloud code job ends, only 1 user ends up being registered in Backendless.

Could you add some logging to your hosted service and see how many times it is invoked?

I added logs. What’s curious is that put “Info” events at the entry point and exit point of my function, but only a single log event was written. Even as I run the job over and over, with more accounts being created in Backendless, no further log entries are recorded - including exit log events.

Here is the single entry:

2016-04-28 01:35:37,680 | com.backendless.pps.data.Logic | INFO | registerParseUser invoked: johan_argyne

Did you set the log buffering policy to:

Backendless.Logging.setLogReportingPolicy(1, 0)

Yes. Here is the code:

LogBuffer.getInstance().setLogReportingPolicy( 1, 0 );

Logger log = Logger.getLogger( Logic.class );
log.info( "registerParseUser invoked: " + name );

So we know the Hosted service is executed (because users are created), but there is no logging?

That is correct. Logging does not happen.

Could you try putting all the code in the method you call into a try/catch(Throwable t) block and log the exception (if any)?

I just wrapped everything in the function in a try/catch. Here are the very first lines of code in the function. It created the logger, but nothing is actually written in it.

LogBuffer.getInstance().setLogReportingPolicy(1, 0);
Logger log = Logger.getLogger("registerParseUserLogger");
log.info("registerParseUser invoked: " + name);

I’ve set the log sensitivity to “All”. Despite all this, rows are still being added to the Backendless user table, so the function is definitely being called.

If I understood correctly, the original problem where the code would complete only once is resolved. The new problem is with logging. Is this correct?

The original problem still remains. It is only compounded by the fact that we can’t get logging inside the function to determine what is happening.

I can see now that the code only creating one Backendless account is not always true. In some cases, 2 or 3 users are created per run - but never the amount that should be created, which can be in the dozens.

When I inspect the logs on the Parse side, I do see where I make multiple calls within a loop to

https://api.backendless.com/<version>/services/<businesslogic>/1.0/registerParseUser

Does each call create only one user?

Do all calls go out sequentially (one waits for the completion of the previous)?
Have you tried running your service in the debug (local) mode?

Yes, each call creates a single user.

The calls go out asynchronously, as all Parse Cloud code HTTPRequests are asynchronous to my knowledge.

Yes, when walking through the code in debug mode, it executes once, which creates a single user account.

What if you do not “walk through the code” in the debug mode, but let the local code runner just run? Does it handle multiple requests?

I did as you suggested and found something interesting. It looks like I have some sort of concurrency/threading issue.

As the code runs, the variables change values sometimes mid-execution, which leads to random errors as various lookups don’t complete since the lookups are against values that are valid for the next or previous person in the loop. It appears that the problem lies with not executing the entire function in its entirety for each call before beginning execution of the next call. Take for example the following code snippet:

String uniqueId = "";
// the following line is required to avoid buffering in server code
LogBuffer.getInstance().setLogReportingPolicy(1, 0);
Logger log = Logger.getLogger("registerParseUserLogger");
log.info("registerParseUser invoked: " + name);

try {
   Backendless.UserService.login(username, pwd, true);

While debugging the code above, the log.info line executes 5 times in a row (since the function was called 5 times) before the try block executes even once.

If the log.info call is executed 5 times, it means your hosted service method was called 5 times. This contradicts the hypothesis that the hosted service runs only once.

Some other things do not make sense for me. For example, when you refer to a “loop”, I assume you’d have it on the Parse’s side, but I cannot see where you’d have a loop in your Hosted service code.

Also, I do not understand what you’re doing with the login call in the code snipped you showed. It might be an irrelevant question, but it muddies my understanding of the problem.