Make the enqueue() of a continuation transactional.
Test: Updated unit tests
Change-Id: Iecd60d247b008856a59fb8f61c24d0e9f86e54ae
diff --git a/background/workmanager/src/androidTest/java/android/arch/background/workmanager/impl/WorkContinuationImplTest.java b/background/workmanager/src/androidTest/java/android/arch/background/workmanager/impl/WorkContinuationImplTest.java
index 572b3e6..de17404 100644
--- a/background/workmanager/src/androidTest/java/android/arch/background/workmanager/impl/WorkContinuationImplTest.java
+++ b/background/workmanager/src/androidTest/java/android/arch/background/workmanager/impl/WorkContinuationImplTest.java
@@ -16,58 +16,104 @@
package android.arch.background.workmanager.impl;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
+import android.arch.background.workmanager.TestLifecycleOwner;
import android.arch.background.workmanager.Work;
-import android.arch.background.workmanager.impl.utils.EnqueueRunnable;
-import android.arch.background.workmanager.impl.utils.taskexecutor.TaskExecutor;
+import android.arch.background.workmanager.executors.SynchronousExecutorService;
+import android.arch.background.workmanager.impl.utils.taskexecutor.InstantTaskExecutorRule;
import android.arch.background.workmanager.worker.TestWorker;
+import android.arch.core.executor.ArchTaskExecutor;
+import android.arch.lifecycle.Lifecycle;
+import android.content.Context;
+import android.support.annotation.NonNull;
+import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
+import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.List;
+
@RunWith(AndroidJUnit4.class)
@SmallTest
public class WorkContinuationImplTest {
+ private WorkDatabase mDatabase;
private WorkManagerImpl mWorkManagerImpl;
- private TaskExecutor mTaskExecutor;
+
+ @Rule
+ public InstantTaskExecutorRule mRule = new InstantTaskExecutorRule();
@Before
- public void setup() {
- mWorkManagerImpl = mock(WorkManagerImpl.class);
- mTaskExecutor = mock(TaskExecutor.class);
- when(mWorkManagerImpl.getTaskExecutor()).thenReturn(mTaskExecutor);
+ public void setUp() {
+ ArchTaskExecutor.getInstance().setDelegate(new android.arch.core.executor.TaskExecutor() {
+ @Override
+ public void executeOnDiskIO(@NonNull Runnable runnable) {
+ runnable.run();
+ }
+
+ @Override
+ public void postToMainThread(@NonNull Runnable runnable) {
+ runnable.run();
+ }
+
+ @Override
+ public boolean isMainThread() {
+ return true;
+ }
+ });
+
+ TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
+ lifecycleOwner.mLifecycleRegistry.markState(Lifecycle.State.CREATED);
+
+ Context context = InstrumentationRegistry.getTargetContext();
+ WorkManagerConfiguration configuration = new WorkManagerConfiguration(
+ context,
+ true,
+ new SynchronousExecutorService(),
+ new SynchronousExecutorService(),
+ lifecycleOwner);
+ mWorkManagerImpl = new WorkManagerImpl(context, configuration);
+ mDatabase = mWorkManagerImpl.getWorkDatabase();
+ }
+
+ @After
+ public void tearDown() {
+ List<String> ids = mDatabase.workSpecDao().getAllWorkSpecIds();
+ for (String id : ids) {
+ mWorkManagerImpl.cancelWorkForId(id);
+ }
+ mDatabase.close();
+ ArchTaskExecutor.getInstance().setDelegate(null);
}
@Test
- public void testLazyContinuation_noParent() {
+ public void testContinuation_noParent() {
Work testWork = createTestWorker();
- WorkContinuationImpl continuation = new WorkContinuationImpl(mWorkManagerImpl,
- testWork);
- assertNull(continuation.mParent);
+ WorkContinuationImpl continuation =
+ new WorkContinuationImpl(mWorkManagerImpl, testWork);
- assertEquals(continuation.mIds[0], testWork.getId());
- assertEquals(continuation.mIds.length, 1);
- assertEquals(continuation.mAllIds.size(), 1);
+ assertThat(continuation.getParent(), is(nullValue()));
+ assertThat(continuation.getIds().length, is(1));
+ assertThat(continuation.getIds()[0], is(testWork.getId()));
+ assertThat(continuation.getAllIds().size(), is(1));
}
@Test
- public void testLazyContinuation_singleChain() {
+ public void testContinuation_singleChain() {
Work testWork = createTestWorker();
Work dependentWork = createTestWorker();
WorkContinuationImpl continuation =
@@ -75,59 +121,59 @@
WorkContinuationImpl dependent = (WorkContinuationImpl) (continuation.then(
dependentWork));
- assertNotNull(dependent.mParent);
- assertEquals(dependent.mParent, continuation);
- assertEquals(dependent.mIds.length, 1);
- assertEquals(dependent.mAllIds.size(), 2);
+ assertThat(dependent.getParent(), is(notNullValue()));
+ assertThat(dependent.getParent(), is(continuation));
+ assertThat(dependent.getIds().length, is(1));
+ assertThat(dependent.getIds()[0], is(dependentWork.getId()));
+ assertThat(dependent.getAllIds().size(), is(2));
+ assertThat(
+ dependent.getAllIds(),
+ containsInAnyOrder(dependentWork.getId(), testWork.getId()));
}
@Test
- public void testLazyContinuation_enqueue() {
+ public void testContinuation_enqueue() {
Work testWork = createTestWorker();
WorkContinuationImpl continuation = new WorkContinuationImpl(mWorkManagerImpl,
testWork);
- assertEquals(continuation.mEnqueued, false);
+ assertThat(continuation.isEnqueued(), is(false));
continuation.enqueue();
-
verifyEnqueued(continuation);
- verify(mTaskExecutor, times(1)).executeOnBackgroundThread(any(EnqueueRunnable.class));
}
@Test
- public void testLazyContinuation_chainEnqueue() {
+ public void testContinuation_chainEnqueue() {
Work testWork = createTestWorker();
WorkContinuationImpl continuation =
new WorkContinuationImpl(mWorkManagerImpl, testWork);
WorkContinuationImpl chain = (WorkContinuationImpl) (
continuation.then(createTestWorker()).then(createTestWorker(), createTestWorker()));
-
chain.enqueue();
verifyEnqueued(continuation);
- verify(mTaskExecutor, times(3)).executeOnBackgroundThread(any(EnqueueRunnable.class));
}
@Test
- public void testLazyContinuation_chainEnqueueNoOpOnRetry() {
+ public void testContinuation_chainEnqueueNoOpOnRetry() {
Work testWork = createTestWorker();
WorkContinuationImpl continuation =
new WorkContinuationImpl(mWorkManagerImpl, testWork);
WorkContinuationImpl chain = (WorkContinuationImpl) (
continuation.then(createTestWorker()).then(createTestWorker(), createTestWorker()));
-
chain.enqueue();
verifyEnqueued(continuation);
- verify(mTaskExecutor, times(3)).executeOnBackgroundThread(any(EnqueueRunnable.class));
- chain.enqueue();
- verifyNoMoreInteractions(mTaskExecutor);
+ WorkContinuationImpl spy = spy(chain);
+ spy.enqueue();
+ // Verify no more calls to markEnqueued().
+ verify(spy, times(0)).markEnqueued();
}
private void verifyEnqueued(WorkContinuationImpl continuation) {
- assertEquals(continuation.mEnqueued, true);
- WorkContinuationImpl parent = continuation.mParent;
+ assertThat(continuation.isEnqueued(), is(true));
+ WorkContinuationImpl parent = continuation.getParent();
while (parent != null) {
- assertEquals(parent.mEnqueued, true);
- parent = parent.mParent;
+ assertThat(parent.isEnqueued(), is(true));
+ parent = parent.getParent();
}
}
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkContinuationImpl.java b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkContinuationImpl.java
index a63c347..00ef536 100644
--- a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkContinuationImpl.java
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkContinuationImpl.java
@@ -16,6 +16,7 @@
package android.arch.background.workmanager.impl;
+import android.arch.background.workmanager.BaseWork;
import android.arch.background.workmanager.Work;
import android.arch.background.workmanager.WorkContinuation;
import android.arch.background.workmanager.WorkManager;
@@ -26,7 +27,6 @@
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RestrictTo;
-import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.Log;
@@ -42,45 +42,75 @@
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public class WorkContinuationImpl extends WorkContinuation {
- private static final String TAG = "LzyWrkContinuationImpl";
+ private static final String TAG = "WorkContinuationImpl";
- @VisibleForTesting
- final WorkManagerImpl mWorkManagerImpl;
+ private final WorkManagerImpl mWorkManagerImpl;
+ private final String mUniqueTag;
+ private final @WorkManager.ExistingWorkPolicy int mExistingWorkPolicy;
+ private final BaseWork[] mWork;
+ private final String[] mIds;
+ private final List<String> mAllIds;
+ private boolean mEnqueued;
+ private WorkContinuationImpl mParent;
- final String mUniqueTag;
+ @NonNull
+ public WorkManagerImpl getWorkManagerImpl() {
+ return mWorkManagerImpl;
+ }
- final @WorkManager.ExistingWorkPolicy int mExistingWorkPolicy;
+ @Nullable
+ public String getUniqueTag() {
+ return mUniqueTag;
+ }
- @VisibleForTesting
- final Work[] mWork;
+ public @WorkManager.ExistingWorkPolicy int getExistingWorkPolicy() {
+ return mExistingWorkPolicy;
+ }
- @VisibleForTesting
- final String[] mIds;
+ @NonNull
+ public BaseWork[] getWork() {
+ return mWork;
+ }
- @VisibleForTesting
- final List<String> mAllIds;
+ @NonNull
+ public String[] getIds() {
+ return mIds;
+ }
- @VisibleForTesting
- boolean mEnqueued;
+ public List<String> getAllIds() {
+ return mAllIds;
+ }
- @VisibleForTesting
- WorkContinuationImpl mParent;
+ public boolean isEnqueued() {
+ return mEnqueued;
+ }
- WorkContinuationImpl(@NonNull WorkManagerImpl workManagerImpl, @NonNull Work... work) {
+ /**
+ * Marks the {@link WorkContinuationImpl} as enqueued.
+ */
+ public void markEnqueued() {
+ mEnqueued = true;
+ }
+
+ public WorkContinuationImpl getParent() {
+ return mParent;
+ }
+
+ WorkContinuationImpl(@NonNull WorkManagerImpl workManagerImpl, @NonNull BaseWork... work) {
this(workManagerImpl, null, WorkManager.KEEP_EXISTING_WORK, work, null);
}
WorkContinuationImpl(@NonNull WorkManagerImpl workManagerImpl,
@NonNull String uniqueTag,
@WorkManager.ExistingWorkPolicy int existingWorkPolicy,
- @NonNull Work... work) {
+ @NonNull BaseWork... work) {
this(workManagerImpl, uniqueTag, existingWorkPolicy, work, null);
}
private WorkContinuationImpl(@NonNull WorkManagerImpl workManagerImpl,
String uniqueTag,
@WorkManager.ExistingWorkPolicy int existingWorkPolicy,
- @NonNull Work[] work,
+ @NonNull BaseWork[] work,
@Nullable WorkContinuationImpl parent) {
mWorkManagerImpl = workManagerImpl;
mUniqueTag = uniqueTag;
@@ -126,34 +156,12 @@
@Override
public void enqueue() {
- // TODO(sumir): Change enqueuing to be transactional, where everything gets enqueued
- // together in one pass instead of spawning multiple runnables.
-
// Only enqueue if not already enqueued.
if (!mEnqueued) {
- if (mParent == null) {
- mWorkManagerImpl.getTaskExecutor()
- .executeOnBackgroundThread(
- new EnqueueRunnable(
- mWorkManagerImpl,
- mWork,
- null /* no prerequisites*/,
- mUniqueTag,
- mExistingWorkPolicy));
- } else {
- // has dependencies which need to be enqueued first
- mParent.enqueue();
- // now enqueue the work continuation, given the dependencies have been enqueued.
- mWorkManagerImpl.getTaskExecutor()
- .executeOnBackgroundThread(
- new EnqueueRunnable(
- mWorkManagerImpl,
- mWork,
- mParent.mIds,
- mUniqueTag,
- mExistingWorkPolicy));
- }
- mEnqueued = true;
+ // The runnable walks the heirarchy of the continuations
+ // and marks them enqueued using the markEnqueued() method, parent first.
+ mWorkManagerImpl.getTaskExecutor()
+ .executeOnBackgroundThread(new EnqueueRunnable(this));
} else {
Log.w(TAG,
String.format("Already enqueued work ids (%s).", TextUtils.join(", ", mIds)));
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkManagerImpl.java b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkManagerImpl.java
index 3301d0f..b1b828b 100644
--- a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkManagerImpl.java
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/WorkManagerImpl.java
@@ -27,7 +27,6 @@
import android.arch.background.workmanager.impl.model.WorkSpecDao;
import android.arch.background.workmanager.impl.utils.BaseWorkHelper;
import android.arch.background.workmanager.impl.utils.CancelWorkRunnable;
-import android.arch.background.workmanager.impl.utils.EnqueueRunnable;
import android.arch.background.workmanager.impl.utils.LiveDataUtils;
import android.arch.background.workmanager.impl.utils.PruneDatabaseRunnable;
import android.arch.background.workmanager.impl.utils.taskexecutor.TaskExecutor;
@@ -158,13 +157,7 @@
@Override
public void enqueue(@NonNull PeriodicWork... periodicWork) {
- mTaskExecutor.executeOnBackgroundThread(
- new EnqueueRunnable(
- this,
- periodicWork,
- null,
- null,
- KEEP_EXISTING_WORK));
+ new WorkContinuationImpl(this, periodicWork).enqueue();
}
@Override
diff --git a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/utils/EnqueueRunnable.java b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/utils/EnqueueRunnable.java
index fd718d1..690e2ca 100644
--- a/background/workmanager/src/main/java/android/arch/background/workmanager/impl/utils/EnqueueRunnable.java
+++ b/background/workmanager/src/main/java/android/arch/background/workmanager/impl/utils/EnqueueRunnable.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,9 +20,9 @@
import static android.arch.background.workmanager.BaseWork.STATUS_SUCCEEDED;
import android.arch.background.workmanager.BaseWork;
-import android.arch.background.workmanager.Work;
import android.arch.background.workmanager.WorkManager;
import android.arch.background.workmanager.impl.InternalWorkImpl;
+import android.arch.background.workmanager.impl.WorkContinuationImpl;
import android.arch.background.workmanager.impl.WorkDatabase;
import android.arch.background.workmanager.impl.WorkManagerImpl;
import android.arch.background.workmanager.impl.model.Dependency;
@@ -30,14 +30,13 @@
import android.arch.background.workmanager.impl.model.WorkTag;
import android.support.annotation.NonNull;
import android.support.annotation.RestrictTo;
-import android.support.annotation.WorkerThread;
import android.text.TextUtils;
import android.util.Log;
import java.util.List;
/**
- * A {@link Runnable} to enqueue a {@link Work} in the database.
+ * Manages the enqueuing of a {@link WorkContinuationImpl}.
*
* @hide
*/
@@ -46,110 +45,151 @@
private static final String TAG = "EnqueueRunnable";
- private WorkManagerImpl mWorkManagerImpl;
- private InternalWorkImpl[] mWorkArray;
- private String[] mPrerequisiteIds;
- private String mUniqueTag;
- @WorkManager.ExistingWorkPolicy private int mExistingWorkPolicy;
+ private final WorkContinuationImpl mWorkContinuation;
- public EnqueueRunnable(WorkManagerImpl workManagerImpl,
+ public EnqueueRunnable(@NonNull WorkContinuationImpl workContinuation) {
+ mWorkContinuation = workContinuation;
+ }
+
+ @Override
+ public void run() {
+ WorkManagerImpl workManagerImpl = mWorkContinuation.getWorkManagerImpl();
+ WorkDatabase workDatabase = workManagerImpl.getWorkDatabase();
+ workDatabase.beginTransaction();
+ try {
+ processContinuation(mWorkContinuation);
+ workDatabase.setTransactionSuccessful();
+ } finally {
+ workDatabase.endTransaction();
+ }
+ }
+
+ private static void processContinuation(@NonNull WorkContinuationImpl workContinuation) {
+ WorkContinuationImpl parent = workContinuation.getParent();
+ if (parent != null) {
+ // When chaining off a completed continuation we need to pay
+ // attention to parents that may have been marked as enqueued before.
+ if (!parent.isEnqueued()) {
+ processContinuation(parent);
+ } else {
+ Log.w(TAG,
+ String.format(
+ "Already enqueued work ids (%s).",
+ TextUtils.join(", ", parent.getIds())));
+ }
+
+ }
+ enqueueContinuation(workContinuation);
+ }
+
+ private static void enqueueContinuation(@NonNull WorkContinuationImpl workContinuation) {
+ WorkContinuationImpl parent = workContinuation.getParent();
+ String[] prerequisiteIds = parent != null ? parent.getIds() : null;
+
+ enqueueWorkWithPrerequisites(
+ workContinuation.getWorkManagerImpl(),
+ workContinuation.getWork(),
+ prerequisiteIds,
+ workContinuation.getUniqueTag(),
+ workContinuation.getExistingWorkPolicy());
+
+ workContinuation.markEnqueued();
+ }
+
+ /**
+ * Enqueues the {@link WorkSpec}'s while keeping track of the prerequisites.
+ */
+ private static void enqueueWorkWithPrerequisites(
+ WorkManagerImpl workManagerImpl,
@NonNull BaseWork[] workArray,
String[] prerequisiteIds,
String uniqueTag,
@WorkManager.ExistingWorkPolicy int existingWorkPolicy) {
- mWorkManagerImpl = workManagerImpl;
- mWorkArray = new InternalWorkImpl[workArray.length];
- for (int i = 0; i < workArray.length; ++i) {
- mWorkArray[i] = (InternalWorkImpl) workArray[i];
- }
- mPrerequisiteIds = prerequisiteIds;
- mUniqueTag = uniqueTag;
- mExistingWorkPolicy = existingWorkPolicy;
- }
- @WorkerThread
- @Override
- public void run() {
- WorkDatabase workDatabase = mWorkManagerImpl.getWorkDatabase();
- workDatabase.beginTransaction();
- try {
- long currentTimeMillis = System.currentTimeMillis();
- boolean hasPrerequisite = (mPrerequisiteIds != null && mPrerequisiteIds.length > 0);
- boolean hasCompletedAllPrerequisites = true;
+ long currentTimeMillis = System.currentTimeMillis();
+ WorkDatabase workDatabase = workManagerImpl.getWorkDatabase();
+
+ InternalWorkImpl[] workImplArray = new InternalWorkImpl[workArray.length];
+ for (int i = 0; i < workArray.length; ++i) {
+ workImplArray[i] = (InternalWorkImpl) workArray[i];
+ }
+
+ boolean hasPrerequisite = (prerequisiteIds != null && prerequisiteIds.length > 0);
+ boolean hasCompletedAllPrerequisites = true;
+
+ if (hasPrerequisite) {
+ // If there are prerequisites, make sure they actually exist before enqueuing
+ // anything. Prerequisites may not exist if we are using unique tags, because the
+ // chain of work could have been wiped out already.
+ for (String id : prerequisiteIds) {
+ WorkSpec prerequisiteWorkSpec = workDatabase.workSpecDao().getWorkSpec(id);
+ if (prerequisiteWorkSpec == null) {
+ Log.e(TAG, "Prerequisite " + id + " doesn't exist; not enqueuing");
+ return;
+ }
+ hasCompletedAllPrerequisites &=
+ (prerequisiteWorkSpec.getStatus() == STATUS_SUCCEEDED);
+ }
+ }
+
+ boolean hasUniqueTag = !TextUtils.isEmpty(uniqueTag);
+ if (hasUniqueTag && !hasPrerequisite) {
+ List<String> existingWorkSpecIds =
+ workDatabase.workSpecDao().getWorkSpecIdsForTag(uniqueTag);
+ if (!existingWorkSpecIds.isEmpty()) {
+ if (existingWorkPolicy == WorkManager.KEEP_EXISTING_WORK) {
+ return;
+ }
+
+ // Cancel all of these workers.
+ CancelWorkRunnable cancelWorkRunnable =
+ new CancelWorkRunnable(workManagerImpl, null, uniqueTag);
+ cancelWorkRunnable.run();
+ // And delete all the database records.
+ workDatabase.workSpecDao().delete(existingWorkSpecIds);
+ }
+ }
+
+ for (InternalWorkImpl work : workImplArray) {
+ WorkSpec workSpec = work.getWorkSpec();
+
+ if (hasPrerequisite && !hasCompletedAllPrerequisites) {
+ workSpec.setStatus(STATUS_BLOCKED);
+ } else {
+ // Set scheduled times only for work without prerequisites. Dependent work
+ // will set their scheduled times when they are unblocked.
+ workSpec.setPeriodStartTime(currentTimeMillis);
+ }
+
+ workDatabase.workSpecDao().insertWorkSpec(workSpec);
if (hasPrerequisite) {
- // If there are prerequisites, make sure they actually exist before enqueuing
- // anything. Prerequisites may not exist if we are using unique tags, because the
- // chain of work could have been wiped out already.
- for (String id : mPrerequisiteIds) {
- WorkSpec prerequisiteWorkSpec = workDatabase.workSpecDao().getWorkSpec(id);
- if (prerequisiteWorkSpec == null) {
- Log.e(TAG, "Prerequisite " + id + " doesn't exist; not enqueuing");
- return;
- }
- hasCompletedAllPrerequisites &=
- (prerequisiteWorkSpec.getStatus() == STATUS_SUCCEEDED);
+ for (String prerequisiteId : prerequisiteIds) {
+ Dependency dep = new Dependency(work.getId(), prerequisiteId);
+ workDatabase.dependencyDao().insertDependency(dep);
}
}
- boolean hasUniqueTag = !TextUtils.isEmpty(mUniqueTag);
- if (hasUniqueTag && !hasPrerequisite) {
- List<String> existingWorkSpecIds =
- workDatabase.workSpecDao().getWorkSpecIdsForTag(mUniqueTag);
- if (!existingWorkSpecIds.isEmpty()) {
- if (mExistingWorkPolicy == WorkManager.KEEP_EXISTING_WORK) {
- return;
- }
-
- // Cancel all of these workers.
- CancelWorkRunnable cancelWorkRunnable =
- new CancelWorkRunnable(mWorkManagerImpl, null, mUniqueTag);
- cancelWorkRunnable.run();
- // And delete all the database records.
- workDatabase.workSpecDao().delete(existingWorkSpecIds);
- }
+ for (String tag : work.getTags()) {
+ workDatabase.workTagDao().insert(new WorkTag(tag, work.getId()));
}
- for (InternalWorkImpl work : mWorkArray) {
- WorkSpec workSpec = work.getWorkSpec();
-
- if (hasPrerequisite && !hasCompletedAllPrerequisites) {
- workSpec.setStatus(STATUS_BLOCKED);
- } else {
- // Set scheduled times only for work without prerequisites. Dependent work
- // will set their scheduled times when they are unblocked.
- workSpec.setPeriodStartTime(currentTimeMillis);
- }
-
- workDatabase.workSpecDao().insertWorkSpec(workSpec);
-
- if (hasPrerequisite) {
- for (String prerequisiteId : mPrerequisiteIds) {
- Dependency dep = new Dependency(work.getId(), prerequisiteId);
- workDatabase.dependencyDao().insertDependency(dep);
- }
- }
-
- for (String tag : work.getTags()) {
- workDatabase.workTagDao().insert(new WorkTag(tag, work.getId()));
- }
-
- // Enforce that the unique tag is always present.
- if (hasUniqueTag) {
- workDatabase.workTagDao().insert(new WorkTag(mUniqueTag, work.getId()));
- }
+ // Enforce that the unique tag is always present.
+ if (hasUniqueTag) {
+ workDatabase.workTagDao().insert(new WorkTag(uniqueTag, work.getId()));
}
- workDatabase.setTransactionSuccessful();
+ }
- // Schedule in the background if there are no prerequisites. Foreground scheduling
- // happens automatically if a ForegroundProcessor is available.
- if (!hasPrerequisite) {
- for (InternalWorkImpl work : mWorkArray) {
- mWorkManagerImpl.getBackgroundScheduler().schedule(work.getWorkSpec());
- }
+ // TODO(rahulrav@) It's dangerous to ask the background scheduler to schedule things.
+ // Revisit this and see if there is a better way to do this, after the transaction
+ // has settled.
+
+ // Schedule in the background if there are no prerequisites. Foreground scheduling
+ // happens automatically if a ForegroundProcessor is available.
+ if (!hasPrerequisite) {
+ for (InternalWorkImpl work : workImplArray) {
+ workManagerImpl.getBackgroundScheduler().schedule(work.getWorkSpec());
}
- } finally {
- workDatabase.endTransaction();
}
}
}