Created
August 2, 2016 15:30
-
-
Save lujop/ba480de9ad061a99758ff5cebcc10cec to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package cat.joanpujol.firebase; | |
import com.google.firebase.database.FirebaseDatabase; | |
import java.util.Arrays; | |
import java.util.HashSet; | |
import java.util.Set; | |
import java.util.concurrent.Callable; | |
import java.util.concurrent.ScheduledFuture; | |
import java.util.concurrent.ScheduledThreadPoolExecutor; | |
import java.util.concurrent.TimeUnit; | |
import timber.log.Timber; | |
/** | |
* Created by lujop on 26/07/16. | |
*/ | |
public class FirebaseOnlineTracker { | |
private static FirebaseOnlineTracker INSTANCE; | |
private ScheduledThreadPoolExecutor threadPoolExecutor; | |
private Set<OnlineRequest> requests = new HashSet<>(); | |
private ScheduledFuture<Void> goingOffline; | |
private boolean online; | |
private FirebaseOnlineTracker(ScheduledThreadPoolExecutor spe) { | |
this.threadPoolExecutor = spe; | |
} | |
public static void init(ScheduledThreadPoolExecutor spe) { | |
if(INSTANCE==null) { | |
INSTANCE = new FirebaseOnlineTracker(spe); | |
Timber.i("FirebaseOnlineTracker initialized"); | |
} else { | |
throw new RuntimeException("FirebaseOnlineTracker already initialized"); | |
} | |
} | |
public static FirebaseOnlineTracker get() { | |
return INSTANCE; | |
} | |
public synchronized OnlineRequest requestOnline(String reason) { | |
OnlineRequest request = new OnlineRequest(reason); | |
if(requests.isEmpty()) { | |
if(goingOffline!=null) { | |
goingOffline.cancel(true); | |
Timber.d("Cancelling going offline due t %s",reason); | |
goingOffline = null; | |
} | |
FirebaseDatabase.getInstance().goOnline(); | |
boolean wasOnline = online; | |
online = true; | |
if(wasOnline) | |
Timber.i("Asking firebase to go online for %s",reason); | |
} else { | |
Timber.v("Increasing reference count due to %s. Already online",reason); | |
} | |
requests.add(request); | |
return request; | |
} | |
public synchronized void releaseOnline(OnlineRequest request) { | |
boolean removed = requests.remove(request); | |
if(!removed) | |
Timber.w("OnlineRequest not already present"); | |
if(requests.isEmpty()) { | |
if(goingOffline==null) { | |
Timber.v("No active online requests. Will schedule go offline in 1 minute due to %s",request.reason); | |
goingOffline = threadPoolExecutor.schedule(goOfflineCallable, 1, TimeUnit.MINUTES); | |
} else { | |
Timber.v("No need to schedule offline. There is already a scheduled job. Request due to %s",request.reason); | |
} | |
} | |
} | |
public synchronized void logStatus() { | |
Timber.i("Online=%b. GoingOffline=%b Requests:",online, goingOffline!=null, requests.toString()); | |
} | |
private final Callable<Void> goOfflineCallable = new Callable<Void>() { | |
@Override | |
public Void call() throws Exception { | |
synchronized (FirebaseOnlineTracker.this) { | |
Timber.i("Asking firebase to go offline"); | |
FirebaseDatabase.getInstance().goOffline(); | |
online = false; | |
goingOffline = null; | |
return null; | |
} | |
} | |
}; | |
public static class OnlineRequest { | |
private String reason; | |
private StackTraceElement[] stackTrace; | |
public OnlineRequest(String reason) { | |
stackTrace = Thread.currentThread().getStackTrace(); | |
this.reason = reason; | |
} | |
@Override | |
public String toString() { | |
return "OnlineRequest{" + "stackTrace=" + Arrays.toString(stackTrace) + " reason="+reason+'}'; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment