Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Determining Status of a Replication in Couchbase Lite

DZone's Guide to

Determining Status of a Replication in Couchbase Lite

Couchbase Lite runs replications with background threads. It's very helpful, but you must be careful to avoid mistakes in detecting the state of a replication.

· Database Zone
Free Resource

Learn how to move from MongoDB to Couchbase Server for consistent high performance in distributed environments at any scale.

Couchbase Lite runs replications (syncs) using background threads. Starting and stopping replications doesn’t happen synchronously. This can lead to mistakes in detecting the state of a replication.

The Replication class has, depending on the platform, either a running property or a convenience routine like isRunning(). This is a lightweight way of checking the status of a replication.

Using it can lead to unexpected results, though. For example, I recently wrote a utility that uses continuous replications. I have a toggle button to start and stop them. It’s tempting to use isRunning to update the button state. Turns out, this is a bad idea. That's not surprising, given changes happen in the background, but easy to overlook.

Instead, the preferred approach uses a change listener. Here’s an example.

We have two classes. The database helper class wraps some standard operations for simplicity. I added an interface to employ a callback pattern. The client class has to implement it. The helper class digests the Couchbase Lite change notification before passing anything to the client. This gives a nice separation of concerns.

The code listings below are outlines. They only show essentials. Let’s look at the helper class first.

public class DBHelper implements Replication.ChangeListener {
  private boolean replicationActive = false;
  private List stateListeners = new ArrayList<>();
  ...

  public interface ReplicationStateListener {
    void onChange(boolean isActive);
  }

  public void startReplication(URL gateway, boolean continuous) {
    ...

    pushReplication.addChangeListener(this);
    pushReplication.start();
  }

  public void stopReplication() {
    ...
  }

  public void addReplicationStateListener(ReplicationStateListener listener) {
    stateListeners.add(listener);
  }

  public void removeReplicationStateListener(ReplicationStateListener listener) {
    stateListeners.remove(listener);
  }

  // Replication.ChangeListener
  @Override
  public void changed(Replication.ChangeEvent changeEvent) {
    if (changeEvent.getError() != null) {
      Throwable lastError = changeEvent.getError();

      // React to the error

      return;
    }

    if (changeEvent.getTransition() == null) return;

    ReplicationState dest = changeEvent.getTransition().getDestination();

    replicationActive = ((dest == ReplicationState.STOPPING || dest == ReplicationState.STOPPED) ? false : true);

    stateListeners.forEach(listener -> listener.onChange(replicationActive));
  }
}

We see that DBHelper implements the Replication.ChangeListener interface. This is an interface defined by Couchbase Lite. In startReplication, we add this listener to the replication. It has one method to override: changed. The ChangeEvent passed in can have several different values. In the example, I check for errors first and notify the user if one occurs. Otherwise I check to see if this is a replication state transition event. The destination state can be one of INITIAL, RUNNING, IDLE, OFFLINE, STOPPING, or STOPPED.

In this case, I just want to know if the replication is shutting down, so I simplify the return value. I allow clients to register more than one listener, so the last bit of code loops over all the callbacks and invokes them.

The client class is even simpler. I have the class implement the needed interface from the helper class. Just register the listener during instance construction, and have onChange do whatever you need in the UI.

public class Client implements DBHelper.ReplicationStateListener {
  private DBHelper service = DBHelper.getInstance();
  ...

  public Client() {
    service.addReplicationStateListener(this);
  }

  ...

  // DBHelper.ReplicationStateListener
  @Override
  public void onChange(boolean isActive) {
    // Code to handle the change
  }
}

This code is drawn from a tool I built. Read about the tool itself in this post. You can find the source code on GitHub here.

Want to deliver a whole new level of customer experience? Learn how to make your move from MongoDB to Couchbase Server.

Topics:
couchbase lite ,database ,replications ,status check

Published at DZone with permission of Hod Greeley. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}