Search in sources :

Example 6 with RealmAsyncTaskImpl

use of io.realm.internal.async.RealmAsyncTaskImpl in project realm-java by realm.

the class SyncSession method refreshAccessToken.

// Authenticate by getting access tokens for the specific Realm
private void refreshAccessToken(final AuthenticationServer authServer) {
    // Authenticate in a background thread. This allows incremental backoff and retries in a safe manner.
    clearScheduledAccessTokenRefresh();
    Future<?> task = SyncManager.NETWORK_POOL_EXECUTOR.submit(new ExponentialBackoffTask<AuthenticateResponse>() {

        @Override
        protected AuthenticateResponse execute() {
            if (!isClosed && !Thread.currentThread().isInterrupted()) {
                return authServer.refreshUser(getUser().getSyncUser().getUserToken(), configuration.getServerUrl(), getUser().getSyncUser().getAuthenticationUrl());
            }
            return null;
        }

        @Override
        protected void onSuccess(AuthenticateResponse response) {
            synchronized (SyncSession.this) {
                if (!isClosed && !Thread.currentThread().isInterrupted()) {
                    RealmLog.debug("Access Token refreshed successfully, Sync URL: " + configuration.getServerUrl());
                    if (nativeRefreshAccessToken(configuration.getPath(), response.getAccessToken().value(), configuration.getUser().getAuthenticationUrl().toString())) {
                        // replaced the user old access_token
                        ObjectServerUser.AccessDescription desc = new ObjectServerUser.AccessDescription(response.getAccessToken(), configuration.getPath(), configuration.shouldDeleteRealmOnLogout());
                        getUser().getSyncUser().addRealm(configuration.getServerUrl(), desc);
                        // schedule the next refresh
                        scheduleRefreshAccessToken(authServer, response.getAccessToken().expiresMs());
                    }
                }
            }
        }

        @Override
        protected void onError(AuthenticateResponse response) {
            if (!isClosed && !Thread.currentThread().isInterrupted()) {
                onGoingAccessTokenQuery.set(false);
                RealmLog.error("Unrecoverable error, while refreshing the access Token (" + response.getError().toString() + ") reschedule will not happen");
            }
        }
    });
    refreshTokenNetworkRequest = new RealmAsyncTaskImpl(task, SyncManager.NETWORK_POOL_EXECUTOR);
}
Also used : AuthenticateResponse(io.realm.internal.network.AuthenticateResponse) RealmAsyncTaskImpl(io.realm.internal.async.RealmAsyncTaskImpl) ObjectServerUser(io.realm.internal.objectserver.ObjectServerUser)

Example 7 with RealmAsyncTaskImpl

use of io.realm.internal.async.RealmAsyncTaskImpl in project realm-java by realm.

the class Realm method executeTransactionAsync.

/**
 * Similar to {@link #executeTransactionAsync(Transaction)}, but also accepts an OnSuccess and OnError callbacks.
 *
 * @param transaction {@link io.realm.Realm.Transaction} to execute.
 * @param onSuccess callback invoked when the transaction succeeds.
 * @param onError callback invoked when the transaction fails.
 * @return a {@link RealmAsyncTask} representing a cancellable task.
 * @throws IllegalArgumentException if the {@code transaction} is {@code null}, or if the realm is opened from
 * another thread.
 */
public RealmAsyncTask executeTransactionAsync(final Transaction transaction, @Nullable final Realm.Transaction.OnSuccess onSuccess, @Nullable final Realm.Transaction.OnError onError) {
    checkIfValid();
    // noinspection ConstantConditions
    if (transaction == null) {
        throw new IllegalArgumentException("Transaction should not be null");
    }
    if (isFrozen()) {
        throw new IllegalStateException("Write transactions on a frozen Realm is not allowed.");
    }
    // Avoid to call canDeliverNotification() in bg thread.
    final boolean canDeliverNotification = sharedRealm.capabilities.canDeliverNotification();
    // the results.
    if ((onSuccess != null || onError != null)) {
        sharedRealm.capabilities.checkCanDeliverNotification("Callback cannot be delivered on current thread.");
    }
    // We need to use the same configuration to open a background OsSharedRealm (i.e Realm)
    // to perform the transaction
    final RealmConfiguration realmConfiguration = getConfiguration();
    // We need to deliver the callback even if the Realm is closed. So acquire a reference to the notifier here.
    final RealmNotifier realmNotifier = sharedRealm.realmNotifier;
    final Future<?> pendingTransaction = asyncTaskExecutor.submitTransaction(new Runnable() {

        @Override
        public void run() {
            if (Thread.currentThread().isInterrupted()) {
                return;
            }
            OsSharedRealm.VersionID versionID = null;
            Throwable exception = null;
            final Realm bgRealm = Realm.getInstance(realmConfiguration);
            bgRealm.beginTransaction();
            try {
                transaction.execute(bgRealm);
                if (Thread.currentThread().isInterrupted()) {
                    return;
                }
                bgRealm.commitTransaction();
                // The bgRealm needs to be closed before post event to caller's handler to avoid concurrency
                // problem. This is currently guaranteed by posting callbacks later below.
                versionID = bgRealm.sharedRealm.getVersionID();
            } catch (final Throwable e) {
                exception = e;
            } finally {
                try {
                    if (bgRealm.isInTransaction()) {
                        bgRealm.cancelTransaction();
                    }
                } finally {
                    bgRealm.close();
                }
            }
            final Throwable backgroundException = exception;
            final OsSharedRealm.VersionID backgroundVersionID = versionID;
            // Cannot be interrupted anymore.
            if (canDeliverNotification) {
                if (backgroundVersionID != null && onSuccess != null) {
                    realmNotifier.post(new Runnable() {

                        @Override
                        public void run() {
                            if (isClosed()) {
                                // The caller Realm is closed. Just call the onSuccess. Since the new created Realm
                                // cannot be behind the background one.
                                onSuccess.onSuccess();
                                return;
                            }
                            if (sharedRealm.getVersionID().compareTo(backgroundVersionID) < 0) {
                                sharedRealm.realmNotifier.addTransactionCallback(new Runnable() {

                                    @Override
                                    public void run() {
                                        onSuccess.onSuccess();
                                    }
                                });
                            } else {
                                onSuccess.onSuccess();
                            }
                        }
                    });
                } else if (backgroundException != null) {
                    realmNotifier.post(new Runnable() {

                        @Override
                        public void run() {
                            if (onError != null) {
                                onError.onError(backgroundException);
                            } else {
                                throw new RealmException("Async transaction failed", backgroundException);
                            }
                        }
                    });
                }
            } else {
                if (backgroundException != null) {
                    // Throw in the worker thread since the caller thread cannot get notifications.
                    throw new RealmException("Async transaction failed", backgroundException);
                }
            }
        }
    });
    return new RealmAsyncTaskImpl(pendingTransaction, asyncTaskExecutor);
}
Also used : RealmAsyncTaskImpl(io.realm.internal.async.RealmAsyncTaskImpl) RealmException(io.realm.exceptions.RealmException) RealmNotifier(io.realm.internal.RealmNotifier) OsSharedRealm(io.realm.internal.OsSharedRealm)

Aggregations

RealmAsyncTaskImpl (io.realm.internal.async.RealmAsyncTaskImpl)7 RealmException (io.realm.exceptions.RealmException)2 RealmNotifier (io.realm.internal.RealmNotifier)2 AuthenticateResponse (io.realm.internal.network.AuthenticateResponse)2 ObjectServerUser (io.realm.internal.objectserver.ObjectServerUser)2 Handler (android.os.Handler)1 Capabilities (io.realm.internal.Capabilities)1 OsSharedRealm (io.realm.internal.OsSharedRealm)1 AndroidCapabilities (io.realm.internal.android.AndroidCapabilities)1 AndroidRealmNotifier (io.realm.internal.android.AndroidRealmNotifier)1 MalformedURLException (java.net.MalformedURLException)1 URISyntaxException (java.net.URISyntaxException)1 ThreadPoolExecutor (java.util.concurrent.ThreadPoolExecutor)1 JSONException (org.json.JSONException)1