@Override public void execute() throws NoSuchStageException { final String name = getEngineName(); Logger.debug(LOG_TAG, "Starting execute for " + name); try { if (!this.isEnabled()) { Logger.info(LOG_TAG, "Skipping stage " + name + "."); session.advance(); return; } } catch (MetaGlobalException.MetaGlobalMalformedSyncIDException e) { // Bad engine syncID. This should never happen. Wipe the server. try { session.updateMetaGlobalWith( name, new EngineSettings(Utils.generateGuid(), this.getStorageVersion())); Logger.info( LOG_TAG, "Wiping server because malformed engine sync ID was found in meta/global."); wipeServer(); Logger.info(LOG_TAG, "Wiped server after malformed engine sync ID found in meta/global."); } catch (Exception ex) { session.abort( ex, "Failed to wipe server after malformed engine sync ID found in meta/global."); } } catch (MetaGlobalException.MetaGlobalMalformedVersionException e) { // Bad engine version. This should never happen. Wipe the server. try { session.updateMetaGlobalWith( name, new EngineSettings(Utils.generateGuid(), this.getStorageVersion())); Logger.info( LOG_TAG, "Wiping server because malformed engine version was found in meta/global."); wipeServer(); Logger.info(LOG_TAG, "Wiped server after malformed engine version found in meta/global."); } catch (Exception ex) { session.abort( ex, "Failed to wipe server after malformed engine version found in meta/global."); } } catch (MetaGlobalException.MetaGlobalStaleClientSyncIDException e) { // Our syncID is wrong. Reset client and take the server syncID. Logger.warn( LOG_TAG, "Remote engine syncID different from local engine syncID:" + " resetting local engine and assuming remote engine syncID."); this.resetLocal(e.serverSyncID); } catch (MetaGlobalException e) { session.abort(e, "Inappropriate meta/global; refusing to execute " + name + " stage."); return; } Synchronizer synchronizer; try { synchronizer = this.getConfiguredSynchronizer(session); } catch (NoCollectionKeysSetException e) { session.abort(e, "No CollectionKeys."); return; } catch (URISyntaxException e) { session.abort(e, "Invalid URI syntax for server repository."); return; } catch (NonObjectJSONException e) { session.abort(e, "Invalid persisted JSON for config."); return; } catch (IOException e) { session.abort(e, "Invalid persisted JSON for config."); return; } catch (ParseException e) { session.abort(e, "Invalid persisted JSON for config."); return; } Logger.debug(LOG_TAG, "Invoking synchronizer."); synchronizer.synchronize(session.getContext(), this); Logger.debug(LOG_TAG, "Reached end of execute."); }
/** * Synchronously wipe this stage by instantiating a local repository session and wiping that. * * <p>Logs and re-throws an exception on failure. */ @Override public void wipeLocal() throws Exception { // Reset, then clear data. this.resetLocal(); final WipeWaiter monitor = new WipeWaiter(); final Context context = session.getContext(); final Repository r = this.getLocalRepository(); final Runnable doWipe = new Runnable() { @Override public void run() { r.createSession( new RepositorySessionCreationDelegate() { @Override public void onSessionCreated(final RepositorySession session) { try { session.begin( new RepositorySessionBeginDelegate() { @Override public void onBeginSucceeded(final RepositorySession session) { session.wipe( new RepositorySessionWipeDelegate() { @Override public void onWipeSucceeded() { try { session.finish( new RepositorySessionFinishDelegate() { @Override public void onFinishSucceeded( RepositorySession session, RepositorySessionBundle bundle) { // Hurrah. synchronized (monitor) { monitor.notify(); } } @Override public void onFinishFailed(Exception ex) { // Assume that no finish => no wipe. synchronized (monitor) { monitor.notify(ex, true); } } @Override public RepositorySessionFinishDelegate deferredFinishDelegate(ExecutorService executor) { return this; } }); } catch (InactiveSessionException e) { // Cannot happen. Call for safety. synchronized (monitor) { monitor.notify(e, true); } } } @Override public void onWipeFailed(Exception ex) { session.abort(); synchronized (monitor) { monitor.notify(ex, true); } } @Override public RepositorySessionWipeDelegate deferredWipeDelegate( ExecutorService executor) { return this; } }); } @Override public void onBeginFailed(Exception ex) { session.abort(); synchronized (monitor) { monitor.notify(ex, true); } } @Override public RepositorySessionBeginDelegate deferredBeginDelegate( ExecutorService executor) { return this; } }); } catch (InvalidSessionTransitionException e) { session.abort(); synchronized (monitor) { monitor.notify(e, true); } } } @Override public void onSessionCreateFailed(Exception ex) { synchronized (monitor) { monitor.notify(ex, false); } } @Override public RepositorySessionCreationDelegate deferredCreationDelegate() { return this; } }, context); } }; final Thread wiping = new Thread(doWipe); synchronized (monitor) { wiping.start(); try { monitor.wait(); } catch (InterruptedException e) { Logger.error(LOG_TAG, "Wipe interrupted."); } } if (!monitor.sessionSucceeded) { Logger.error(LOG_TAG, "Failed to create session for wipe."); throw monitor.error; } if (!monitor.wipeSucceeded) { Logger.error(LOG_TAG, "Failed to wipe session."); throw monitor.error; } Logger.info(LOG_TAG, "Wiping stage complete."); }