That fuck shit the fascists are using
at master 87 lines 3.0 kB view raw
1package org.tm.archive.migrations; 2 3import androidx.annotation.NonNull; 4import androidx.annotation.Nullable; 5 6import org.signal.core.util.logging.Log; 7import org.tm.archive.jobmanager.Job; 8import org.tm.archive.jobmanager.JobLogger; 9import org.tm.archive.jobmanager.impl.BackoffUtil; 10import org.tm.archive.util.FeatureFlags; 11 12/** 13 * A base class for jobs that are intended to be used in {@link ApplicationMigrations}. Some 14 * sensible defaults are provided, as well as enforcement that jobs have the correct queue key, 15 * never expire, and have at most one instance (to avoid double-migrating). 16 * 17 * These jobs can never fail, or else the JobManager will skip over them. As a result, if they are 18 * neither successful nor retryable, they will crash the app. 19 */ 20abstract class MigrationJob extends Job { 21 22 private static final String TAG = Log.tag(MigrationJob.class); 23 24 MigrationJob(@NonNull Parameters parameters) { 25 super(parameters.toBuilder() 26 .setQueue(Parameters.MIGRATION_QUEUE_KEY) 27 .setMaxInstancesForFactory(1) 28 .setLifespan(Parameters.IMMORTAL) 29 .setMaxAttempts(Parameters.UNLIMITED) 30 .build()); 31 } 32 33 @Override 34 public @Nullable byte[] serialize() { 35 return null; 36 } 37 38 @Override 39 public @NonNull Result run() { 40 try { 41 Log.i(TAG, "About to run " + getClass().getSimpleName()); 42 performMigration(); 43 return Result.success(); 44 } catch (RuntimeException e) { 45 Log.w(TAG, JobLogger.format(this, "Encountered a runtime exception."), e); 46 throw new FailedMigrationError(e); 47 } catch (Exception e) { 48 if (shouldRetry(e)) { 49 Log.w(TAG, JobLogger.format(this, "Encountered a retryable exception."), e); 50 return Result.retry(BackoffUtil.exponentialBackoff(getRunAttempt() + 1, FeatureFlags.getDefaultMaxBackoff())); 51 } else { 52 Log.w(TAG, JobLogger.format(this, "Encountered a non-runtime fatal exception."), e); 53 throw new FailedMigrationError(e); 54 } 55 } 56 } 57 58 @Override 59 public void onFailure() { 60 throw new AssertionError("This job should never fail. " + getClass().getSimpleName()); 61 } 62 63 /** 64 * @return True if you want the UI to be blocked by a spinner if the user opens the application 65 * during the migration, otherwise false. 66 */ 67 abstract boolean isUiBlocking(); 68 69 /** 70 * Do the actual work of your migration. 71 */ 72 abstract void performMigration() throws Exception; 73 74 /** 75 * @return True if you should retry this job based on the exception type, otherwise false. 76 * Returning false will result in a crash and your job being re-run upon app start. 77 * This could result in a crash loop, but considering that this is for an application 78 * migration, this is likely preferable to skipping it. 79 */ 80 abstract boolean shouldRetry(@NonNull Exception e); 81 82 private static class FailedMigrationError extends Error { 83 FailedMigrationError(Throwable t) { 84 super(t); 85 } 86 } 87}