0

I have a singleton that keeps track of the logged in user. I have a getInstance() method that fetches the user from the database if instance is null. My question is if it is ok to keep the subscription open so that any updates to the database will automatically update the instance variable.

Here is what my class looks like:

public class CurrentUser {

private static User instance;

private CurrentUser(){
    //Singleton
}

public static void init(){
    getCurrentuserFromDatabase();
}

public static User getInstance(){
    if(instance == null){
        getCurrentuserFromDatabase();
    }
    return instance;
}

private static void getCurrentuserFromDatabase(){
    DatabaseModule.getStorIOSQLite()
            .get()
            .object(User.class)
            .withQuery(
                    //Select a user from the User table whose session token is not null and is not empty
                    Query.builder()
                    .table(UsersTable.TABLE)
                    .where(UsersTable.COLUMN_SESSION_TOKEN + "IS NOT NULL AND " +
                            UsersTable.COLUMN_SESSION_TOKEN + " != \"\"")
            .build())
            .prepare()
            .createObservable()
            .subscribeOn(Schedulers.io())
            .observeOn(Schedulers.newThread())
            .subscribe(new Observer<User>() {
                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {
                    //user wasn't logged in
                }

                @Override
                public void onNext(User user) {
                    instance = user;
                }
            });
}

}

Should I definitely be calling unsubscribe somewhere? If so where? Inside onComplete()?

Sree
  • 2,727
  • 3
  • 29
  • 47

1 Answers1

0

Should I definitely be calling unsubscribe somewhere?

No, if you want to observe changes for this query during whole lifetime of your application process, you don't need to unsubscribe from it!

If so where? Inside onComplete()?

There is no sense to unsubscribe from Rx Subscription in onComplete() because when you receive onComplete(), Subscription already finished and calls to unsubscribe() won't do anything with it.

// P.S. Interesting use case for StorIO!

Hope your User class is immutable and has correctly overridden equals() and hashCode() because it looks like that you're sharing it to all components of the app and more over any update of users table updates the reference to the new object, so it may affect code that already works with user object and then grabs new one.

Artem Zinnatullin
  • 4,305
  • 1
  • 29
  • 43
  • Thanks for the answer. If not in onComplete(), how about in onNext(). I guess my question is where is the most appropriate place to unsubscribe? Also, I don't quite get what you mean in the latter half of you answer. Why do I need to make the class immutable? – Sree Jan 20 '16 at 20:39
  • Well, if you unsubscribe in `onNext()` then you won't receive any updates. – Artem Zinnatullin Jan 20 '16 at 21:29
  • Oh wait, you're filling `User instance` asynchronously and may return `null` as result of `getInstance()`, well, now I'm not sure how do you want your code to work… – Artem Zinnatullin Jan 20 '16 at 21:31
  • Yea, that makes sense. I guess I got too caught up in people telling me to make sure to unsubscribe because of context leaks but I have no such worry here. – Sree Jan 20 '16 at 22:20
  • Sorry, the code is definitely a work in progress. The idea i had was if the user logs out, the instance should be null. – Sree Jan 20 '16 at 22:20