3

For testing purpose I put the following code in the onCreate() of an Activity:

    // Create 50 objects
    for (int i = 0; i < 50; i++) {
        ParseObject obj = new ParseObject("test_obj");
        obj.put("foo", "bar");
        try {
            obj.save();
        } catch (ParseException pe) {
            Log.d("Parsetest", "Failed to save " + pe.toString());
        }
    }

    // Count them
    for (int i = 0; i < 10; i ++) {
        ParseQuery<ParseObject> query = ParseQuery.getQuery("test_obj");
        query.countInBackground(new CountCallback() {
            @Override
            public void done(int count, ParseException e) {
                if (e == null) {
                    Log.d("Parsetest", "Background found " + count + " objects");
                } else {
                    Log.d("Parsetest", "Query issue" + e.toString());
                }
            }
        });
    }

I would expect the count to be always fifty, however running this code yields something like:

D/Parsetest(17761): Background found 0 objects
D/Parsetest(17761): Background found 0 objects
D/Parsetest(17761): Background found 0 objects
D/Parsetest(17761): Background found 0 objects
D/Parsetest(17761): Background found 0 objects
D/Parsetest(17761): Background found 0 objects
D/Parsetest(17761): Background found 50 objects
D/Parsetest(17761): Background found 0 objects
D/Parsetest(17761): Background found 0 objects
D/Parsetest(17761): Background found 0 objects

Can somebody explain this behavior and how to correct this ?

1 Answer 1

1

Without knowing further details, I'm inclined to believe the inconsistency is due to threading and the mixing of synchronous/asynchronous calls.

For example, calling obj.save(); is synchronous (reference), however, without seeing the rest of your code, it's possible that the synchronous save is being executed on a background thread.

Additionally, query.countInBackground is asynchronous and is being called multiple times with a for loop. This is going to simultaneously create 10 separate background processes to query Parse for the count of objects and depending on how the save is handled there could be race conditions.

Lastly, there are documented limitations on count operations with Parse.

Count queries are rate limited to a maximum of 160 requests per minute. They can also return inaccurate results for classes with more than 1,000 objects. Thus, it is preferable to architect your application to avoid this sort of count operation (by using counters, for example.)

From Héctor Ramos on the Parse Developers Google group,

Count queries have always been expensive once you throw some constraints in. If you only care about the total size of the collection, you can run a count query without any constraints and that one should be pretty fast, as getting the total number of records is a different problem than counting how many of these match an arbitrary list of constraints. This is just the reality of working with database systems.

Given the cost of count operations, it is possible that Parse has mechanisms in place to prevent rapid bursts of count operations from a given client.

If you are needing to perform count operations often, the recommended approach is to use cloud code afterSave hooks to increment/decrement a counter as needed.

Sign up to request clarification or add additional context in comments.

3 Comments

There is not much else code except for the Android boiler plate. Running the count in a loop is simple to illustrate the count is behaving unstable/unreliable. The same behavior exists when doing multiple invocations (so even with a populated database). And the same also occurs when doing everything fully synchronous. And next to this I'm nowhere the sizes mentioned that will cause any ratelimiting.
What happens if you only perform one count query? Does it work every time? I wouldn't be surprised if Parse has precautions in place to limit a sudden burst of count operations from the same client given how expensive count operations are. Maybe that is the case since 1 of the 10 is working
You may also want to check out this link if you haven't come across it yet. I'll update the answer with an excerpt. groups.google.com/forum/#!topic/parse-developers/1GOv37oTY2k

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.