Blog

How to set up cross-platform, multi-type atomic counters

by on March 11, 2015

There are plenty of use cases when mBaaS-powered applications must use a centralized mechanism for incrementing or decrementing a value. There are several approaches for maintaining a counter – some apps use a database, others keep it in the server-side business logic (Cloud Code).

Backendless offers a specialized API for working with atomic counters. The API is cross-platform – any number of different clients (including REST) can work with the same counter and update it concurrently. Every counter in Backendless has a name, which is assigned by the client application. The sample below demonstrates the API for incrementing and retrieving the value of a counter.

    Asynchronous sample (Android and Plain Java):

    IAtomic<Integer> counter = Backendless.Counters.of( "my counter", Integer.class );
    counter.incrementAndGet( new AsyncCallback<Integer>()
    {
        @Override
        public void handleResponse( Integer counterValue )
        {
            System.out.println( "Counter value - " + counterValue );
        }
        @Override
        public void handleFault( BackendlessFault backendlessFault )
        {
            System.out.println( "Server reported an error " + backendlessFault.getMessage() );
        }
    } );

    Synchronous sample (Plain Java only):

    IAtomic<Integer> counter = Backendless.Counters.of( "my counter", Integer.class );
    int counterValue = counter.incrementAndGet();
    System.out.println( "Counter value - " + counterValue );

    -(void)counterIncrementAndGetSync {
        @try {
            id <IAtomic> counter  = [backendless.counters of:@"my counter"];
            NSNumber *counterValue = [counter incrementAndGet];
            NSLog(@"Counter value (SYNC): %@", counterValue);
        }
        @catch (Fault *fault) {
            NSLog(@"Server reported an error(SYNC): %@", fault);
        }
    }

    Asynchronous sample:

    -(void)counterIncrementAndGetAsync {
        id <IAtomic> counter  = [backendless.counters of:@"my counter"];
        [counter
         incrementAndGet:^(NSNumber *counterValue) {
             NSLog(@"Counter value (ASYNC): %@", counterValue);
         }
         error:^(Fault *fault) {
             NSLog(@"Server reported an error (ASYNC): %@", fault);
         }];
    }


    Synchronous sample:

        func counterIncrementAndGetSync() {
            Types.try({ () -> Void in
                var counter = self.backendless.counters.of("my counter")
                var counterValue = counter.incrementAndGet()
                println("Counter value  (SYNC): \(counterValue )")
                },
                catch: { (exception) -> Void in
                    println("Server reported an error (SYNC): \(exception as! Fault)")
                }
            )
        }

    Asynchronous sample:

    func counterIncrementAndGetAsync() {
            var counter = self.backendless.counters.of("my counter")
            counter.incrementAndGet(
                { (var counterValue) -> () in
                    println("Counter value  (ASYNC): \(counterValue )")
                },
                error: { (var fault : Fault!) -> () in
                    println("Server reported an error (ASYNC): \(fault)")
                }
            )
        }
    }

    The API is very easy to use and provides several other features like decrementing a value, performing a conditional update, retrieving the current value, and resetting a counter.