Search in sources :

Example 6 with JobManagerCallbackAdapter

use of com.birbit.android.jobqueue.callback.JobManagerCallbackAdapter in project android-priority-jobqueue by yigit.

the class JobManager method addJobInBackground.

/**
     * Adds a Job in a background thread and calls the provided callback once the Job is added
     * to the JobManager.
     *
     * @param job The Job to be added
     * @param callback The callback to be invoked once Job is saved in the JobManager's queues
     */
public void addJobInBackground(Job job, final AsyncAddCallback callback) {
    if (callback == null) {
        addJobInBackground(job);
        return;
    }
    final String uuid = job.getId();
    addCallback(new JobManagerCallbackAdapter() {

        @Override
        public void onJobAdded(@NonNull Job job) {
            if (uuid.equals(job.getId())) {
                try {
                    callback.onAdded();
                } finally {
                    removeCallback(this);
                }
            }
        }
    });
    addJobInBackground(job);
}
Also used : JobManagerCallbackAdapter(com.birbit.android.jobqueue.callback.JobManagerCallbackAdapter)

Example 7 with JobManagerCallbackAdapter

use of com.birbit.android.jobqueue.callback.JobManagerCallbackAdapter in project android-priority-jobqueue by yigit.

the class KeepAliveTest method testKeepAlive.

@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public void testKeepAlive(final DummyNetworkUtil networkUtil) throws Exception {
    int keepAlive = 3;
    final JobManager jobManager = createJobManager(new Configuration.Builder(RuntimeEnvironment.application).consumerKeepAlive(keepAlive).networkUtil(networkUtil).timer(mockTimer));
    //give it a little time to create first consumer
    final CountDownLatch jobDone = new CountDownLatch(1);
    jobManager.addCallback(new JobManagerCallbackAdapter() {

        @Override
        public void onDone(@NonNull Job job) {
            jobDone.countDown();
        }
    });
    jobManager.addJob(new DummyJob(new Params(0)));
    // Sync on job manager to ensure it handled add requests
    jobManager.count();
    MatcherAssert.assertThat("there should be 1 thread  actively waiting for jobs", jobManager.getActiveConsumerCount(), equalTo(1));
    MatcherAssert.assertThat(jobDone.await(1, TimeUnit.MINUTES), CoreMatchers.is(true));
    // Sync on job manager to ensure it handled add requests
    jobManager.count();
    mockTimer.incrementNs((long) (JobManager.NETWORK_CHECK_INTERVAL + TimeUnit.SECONDS.toNanos(keepAlive) + 1));
    FutureTask<Void> waitForConsumersFuture = new FutureTask<>(new Callable<Void>() {

        @Override
        public Void call() throws Exception {
            jobManager.waitUntilConsumersAreFinished();
            return null;
        }
    });
    new Thread(waitForConsumersFuture).start();
    waitForConsumersFuture.get(keepAlive * 10, TimeUnit.SECONDS);
    jobManager.waitUntilConsumersAreFinished();
    MatcherAssert.assertThat("after keep alive timeout, there should NOT be any threads waiting", jobManager.getActiveConsumerCount(), equalTo(0));
    //disable network and add a network bound job
    networkUtil.setNetworkStatus(NetworkUtil.DISCONNECTED);
    final DummyJob dj1 = new DummyJob(new Params(0).requireNetwork());
    jobManager.addJob(dj1);
    // sync add job request
    jobManager.count();
    mockTimer.incrementNs(JobManager.NETWORK_CHECK_INTERVAL + TimeUnit.SECONDS.toNanos(keepAlive) * 2);
    waitUntilAJobIsDone(jobManager, new WaitUntilCallback() {

        @Override
        public void run() {
            networkUtil.setNetworkStatus(NetworkUtil.METERED);
        }

        @Override
        public void assertJob(Job job) {
            Assert.assertThat("it should be dj1", job, is((Job) dj1));
        }
    });
    MatcherAssert.assertThat("when network is recovered, job should be handled", jobManager.count(), equalTo(0));
}
Also used : JobManagerCallbackAdapter(com.birbit.android.jobqueue.callback.JobManagerCallbackAdapter) Params(com.birbit.android.jobqueue.Params) JobManager(com.birbit.android.jobqueue.JobManager) CountDownLatch(java.util.concurrent.CountDownLatch) DummyJob(com.birbit.android.jobqueue.test.jobs.DummyJob) FutureTask(java.util.concurrent.FutureTask) DummyJob(com.birbit.android.jobqueue.test.jobs.DummyJob) Job(com.birbit.android.jobqueue.Job) TargetApi(android.annotation.TargetApi)

Example 8 with JobManagerCallbackAdapter

use of com.birbit.android.jobqueue.callback.JobManagerCallbackAdapter in project android-priority-jobqueue by yigit.

the class NetworkJobTest method testNetworkJob.

@TargetApi(Build.VERSION_CODES.GINGERBREAD)
@Test
public void testNetworkJob() throws Exception {
    enableDebug();
    JobManagerTestBase.DummyNetworkUtil dummyNetworkUtil = new JobManagerTestBase.DummyNetworkUtil();
    final JobManager jobManager = createJobManager(new Configuration.Builder(RuntimeEnvironment.application).networkUtil(dummyNetworkUtil).timer(mockTimer));
    jobManager.stop();
    DummyJob networkDummyJob = new DummyJob(addRequirement(new Params(5)));
    jobManager.addJob(networkDummyJob);
    DummyJob noNetworkDummyJob = new DummyJob(new Params(2));
    jobManager.addJob(noNetworkDummyJob);
    DummyJob networkPersistentJob = new DummyJob(addRequirement(new Params(6).persist()));
    jobManager.addJob(networkPersistentJob);
    DummyJob noNetworkPersistentJob = new DummyJob(new Params(1).persist());
    jobManager.addJob(noNetworkPersistentJob);
    MatcherAssert.assertThat("count should be correct if there are network and non-network jobs w/o network", jobManager.count(), equalTo(4));
    dummyNetworkUtil.setNetworkStatus(NetworkUtil.METERED);
    MatcherAssert.assertThat("count should be correct if there is network and non-network jobs w/o network", jobManager.count(), equalTo(4));
    dummyNetworkUtil.setNetworkStatus(NetworkUtil.DISCONNECTED);
    final CountDownLatch noNetworkLatch = new CountDownLatch(2);
    jobManager.addCallback(new JobManagerCallbackAdapter() {

        @Override
        public void onAfterJobRun(@NonNull Job job, int resultCode) {
            if (resultCode == JobManagerCallback.RESULT_SUCCEED) {
                MatcherAssert.assertThat("should be a no network job", job.requiresNetwork(), is(false));
                noNetworkLatch.countDown();
                if (noNetworkLatch.getCount() == 0) {
                    jobManager.removeCallback(this);
                }
            }
        }
    });
    jobManager.start();
    MatcherAssert.assertThat(noNetworkLatch.await(1, TimeUnit.MINUTES), is(true));
    MatcherAssert.assertThat("no network jobs should be executed even if there is no network", jobManager.count(), equalTo(2));
    final CountDownLatch networkLatch = new CountDownLatch(2);
    jobManager.addCallback(new JobManagerCallbackAdapter() {

        @Override
        public void onAfterJobRun(@NonNull Job job, int resultCode) {
            if (resultCode == JobManagerCallback.RESULT_SUCCEED) {
                MatcherAssert.assertThat("should be a network job", job.requiresNetwork(), is(true));
                networkLatch.countDown();
                if (networkLatch.getCount() == 0) {
                    jobManager.removeCallback(this);
                }
            }
        }
    });
    dummyNetworkUtil.setNetworkStatus(NetworkUtil.METERED);
    // network check delay, make public?
    mockTimer.incrementMs(10000);
    if (unmetered) {
        MatcherAssert.assertThat("if jobs require unmetered, they should not be run", networkLatch.await(10, TimeUnit.SECONDS), is(false));
        MatcherAssert.assertThat(networkLatch.getCount(), is(2L));
        dummyNetworkUtil.setNetworkStatus(NetworkUtil.UNMETERED);
        // network check delay
        mockTimer.incrementMs(10000);
    }
    MatcherAssert.assertThat(networkLatch.await(1, TimeUnit.MINUTES), is(true));
    MatcherAssert.assertThat("when network is recovered, all network jobs should be automatically consumed", jobManager.count(), equalTo(0));
}
Also used : JobManagerCallbackAdapter(com.birbit.android.jobqueue.callback.JobManagerCallbackAdapter) Configuration(com.birbit.android.jobqueue.config.Configuration) Params(com.birbit.android.jobqueue.Params) JobManager(com.birbit.android.jobqueue.JobManager) CountDownLatch(java.util.concurrent.CountDownLatch) RetryConstraint(com.birbit.android.jobqueue.RetryConstraint) DummyJob(com.birbit.android.jobqueue.test.jobs.DummyJob) DummyJob(com.birbit.android.jobqueue.test.jobs.DummyJob) Job(com.birbit.android.jobqueue.Job) Test(org.junit.Test) TargetApi(android.annotation.TargetApi)

Example 9 with JobManagerCallbackAdapter

use of com.birbit.android.jobqueue.callback.JobManagerCallbackAdapter in project android-priority-jobqueue by yigit.

the class RetryLogicTest method testChangeDelay.

@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public void testChangeDelay(boolean persistent) throws InterruptedException {
    canRun = true;
    RetryJob job = new RetryJob(new Params(1).setPersistent(persistent));
    job.retryLimit = 2;
    retryProvider = new RetryProvider() {

        @Override
        public RetryConstraint build(Job job, Throwable throwable, int runCount, int maxRunCount) {
            RetryConstraint constraint = new RetryConstraint(true);
            constraint.setNewDelayInMs(2000L);
            return constraint;
        }
    };
    final List<Long> runTimes = new ArrayList<>();
    onRunCallback = new Callback() {

        @Override
        public void on(Job job) {
            runTimes.add(mockTimer.nanoTime());
        }
    };
    final Throwable[] callbackError = new Throwable[1];
    final CountDownLatch runLatch = new CountDownLatch(2);
    final JobManager jobManager = createJobManager();
    jobManager.addCallback(new JobManagerCallbackAdapter() {

        @Override
        public void onAfterJobRun(@NonNull Job job, int resultCode) {
            try {
                mockTimer.incrementMs(1999);
                assertThat("no jobs should be ready", jobManager.countReadyJobs(), is(0));
                mockTimer.incrementMs(2);
            } catch (Throwable t) {
                callbackError[0] = t;
            } finally {
                runLatch.countDown();
            }
        }
    });
    jobManager.addJob(job);
    assertThat("on run callbacks should arrive", runLatch.await(100, TimeUnit.MINUTES), is(true));
    assertThat("run callback should not have any errors", callbackError[0], nullValue());
    assertThat("job should be canceled", cancelLatch.await(1, TimeUnit.SECONDS), is(true));
    assertThat("should run 2 times", runCount, is(2));
    long timeInBetween = TimeUnit.NANOSECONDS.toSeconds(runTimes.get(1) - runTimes.get(0));
    assertThat("time between two runs should be at least 2 seconds. " + timeInBetween, 2 <= timeInBetween, is(true));
}
Also used : JobManagerCallbackAdapter(com.birbit.android.jobqueue.callback.JobManagerCallbackAdapter) ArrayList(java.util.ArrayList) Params(com.birbit.android.jobqueue.Params) JobManager(com.birbit.android.jobqueue.JobManager) CountDownLatch(java.util.concurrent.CountDownLatch) RetryConstraint(com.birbit.android.jobqueue.RetryConstraint) RetryConstraint(com.birbit.android.jobqueue.RetryConstraint) DummyJob(com.birbit.android.jobqueue.test.jobs.DummyJob) Job(com.birbit.android.jobqueue.Job) TargetApi(android.annotation.TargetApi)

Example 10 with JobManagerCallbackAdapter

use of com.birbit.android.jobqueue.callback.JobManagerCallbackAdapter in project android-priority-jobqueue by yigit.

the class RetryLogicTest method testChangeDelayOfTheGroup.

@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public void testChangeDelayOfTheGroup(Boolean persistent) throws InterruptedException {
    final JobManager jobManager = createJobManager();
    canRun = true;
    final RetryJob job1 = new RetryJob(new Params(2).setPersistent(Boolean.TRUE.equals(persistent)).groupBy("g1"));
    job1.identifier = "job 1 id";
    RetryJob job2 = new RetryJob(new Params(2).setPersistent(!Boolean.FALSE.equals(persistent)).groupBy("g1"));
    job2.identifier = "job 2 id";
    job1.retryLimit = 2;
    job2.retryLimit = 2;
    final String job1Id = job1.identifier;
    final String job2Id = job2.identifier;
    final PersistableDummyJob postTestJob = new PersistableDummyJob(new Params(1).groupBy("g1").setPersistent(Boolean.TRUE.equals(persistent)));
    final Semaphore jobsCanRun = new Semaphore(4);
    jobsCanRun.acquire(3);
    final Job[] unexpectedRun = new Job[1];
    final CallbackManager callbackManager = JobManagerTrojan.getCallbackManager(jobManager);
    retryProvider = new RetryProvider() {

        @Override
        public RetryConstraint build(Job job, Throwable throwable, int runCount, int maxRunCount) {
            RetryConstraint constraint = new RetryConstraint(true);
            constraint.setNewDelayInMs(2000L);
            JqLog.d("setting new delay in mS to %s. now is %s. job is %s", 2000, mockTimer.nanoTime(), ((RetryJob) job).identifier);
            constraint.setApplyNewDelayToGroup(true);
            return constraint;
        }
    };
    final List<Pair<String, Long>> runTimes = new ArrayList<>();
    final Map<String, Long> cancelTimes = new HashMap<>();
    final Throwable[] lastJobRunOrder = new Throwable[1];
    onRunCallback = new Callback() {

        @Override
        public void on(Job job) {
            if (!callbackManager.waitUntilAllMessagesAreConsumed(30)) {
                lastJobRunOrder[0] = new RuntimeException("consumers did not finish in 30 seconds");
            }
            RetryJob retryJob = (RetryJob) job;
            if (!jobsCanRun.tryAcquire() && unexpectedRun[0] == null) {
                unexpectedRun[0] = job;
            }
            runTimes.add(new Pair<>(retryJob.identifier, mockTimer.nanoTime()));
        }
    };
    onCancelCallback = new CancelCallback() {

        @Override
        public void on(Job job, int cancelReason, Throwable throwable) {
            JqLog.d("on cancel of job %s", job);
            RetryJob retryJob = (RetryJob) job;
            assertThat("Job should cancel only once", cancelTimes.containsKey(retryJob.identifier), is(false));
            cancelTimes.put(retryJob.identifier, mockTimer.nanoTime());
            if (!job.isPersistent() || postTestJob.isPersistent()) {
                if (dummyJobRunLatch.getCount() != 1) {
                    lastJobRunOrder[0] = new Exception("the 3rd job should not run until others cancel fully");
                }
            }
        }
    };
    cancelLatch = new CountDownLatch(2);
    final CountDownLatch jobRunLatch = new CountDownLatch(5);
    final Throwable[] afterJobError = new Throwable[1];
    jobManager.addCallback(new JobManagerCallbackAdapter() {

        @Override
        public void onJobRun(@NonNull Job job, int resultCode) {
            synchronized (this) {
                try {
                    if (job instanceof RetryJob) {
                        RetryJob retryJob = (RetryJob) job;
                        if (retryJob.identifier.equals(job1Id) && retryJob.getCurrentRunCount() == retryJob.getRetryLimit()) {
                            jobsCanRun.release();
                        }
                    }
                } catch (Throwable t) {
                    afterJobError[0] = t;
                }
            }
        }

        @Override
        public void onAfterJobRun(@NonNull Job job, int resultCode) {
            synchronized (this) {
                try {
                    if (job instanceof RetryJob) {
                        assertThat("no job should have run unexpectedly " + jobRunLatch.getCount(), unexpectedRun[0], nullValue());
                        RetryJob retryJob = (RetryJob) job;
                        if (retryJob.getCurrentRunCount() == 2) {
                        // next job should be ready, asserted in onRun
                        } else {
                            mockTimer.incrementMs(1999);
                            assertThat("no jobs should be ready", jobManager.countReadyJobs(), is(0));
                            jobsCanRun.release();
                            mockTimer.incrementMs(2);
                        }
                    }
                } catch (Throwable t) {
                    afterJobError[0] = t;
                    jobRunLatch.countDown();
                    jobRunLatch.countDown();
                    jobRunLatch.countDown();
                    jobRunLatch.countDown();
                    jobRunLatch.countDown();
                } finally {
                    jobRunLatch.countDown();
                }
            }
        }
    });
    jobManager.addJob(job1);
    jobManager.addJob(job2);
    jobManager.addJob(postTestJob);
    assertThat("all expected jobs should run", jobRunLatch.await(5, TimeUnit.MINUTES), is(true));
    assertThat("on run assertions should all pass", afterJobError[0], nullValue());
    assertThat("jobs should be canceled", cancelLatch.await(1, TimeUnit.MILLISECONDS), is(true));
    assertThat("should run 4 times", runTimes.size(), is(4));
    for (int i = 0; i < 4; i++) {
        assertThat("first two runs should be job1, last two jobs should be job 2. checking " + i, runTimes.get(i).first, is(i < 2 ? job1Id : job2Id));
    }
    long timeInBetween = TimeUnit.NANOSECONDS.toSeconds(runTimes.get(1).second - runTimes.get(0).second);
    assertThat("time between two runs should be at least 2 seconds. job 1 and 2" + ":" + timeInBetween, 2 <= timeInBetween, is(true));
    timeInBetween = TimeUnit.NANOSECONDS.toSeconds(runTimes.get(3).second - runTimes.get(2).second);
    assertThat("time between two runs should be at least 2 seconds. job 3 and 4" + ":" + timeInBetween, 2 <= timeInBetween, is(true));
    assertThat("the other job should run after others are cancelled", dummyJobRunLatch.await(1, TimeUnit.SECONDS), is(true));
    // another job should just run
    dummyJobRunLatch = new CountDownLatch(1);
    jobManager.addJob(new PersistableDummyJob(new Params(1).groupBy("g1")));
    assertThat("a newly added job should just run quickly", dummyJobRunLatch.await(500, TimeUnit.MILLISECONDS), is(true));
    assertThat(lastJobRunOrder[0], nullValue());
}
Also used : JobManagerCallbackAdapter(com.birbit.android.jobqueue.callback.JobManagerCallbackAdapter) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) JobManager(com.birbit.android.jobqueue.JobManager) Semaphore(java.util.concurrent.Semaphore) RetryConstraint(com.birbit.android.jobqueue.RetryConstraint) DummyJob(com.birbit.android.jobqueue.test.jobs.DummyJob) Job(com.birbit.android.jobqueue.Job) Pair(android.util.Pair) Params(com.birbit.android.jobqueue.Params) CountDownLatch(java.util.concurrent.CountDownLatch) CallbackManager(com.birbit.android.jobqueue.CallbackManager) RetryConstraint(com.birbit.android.jobqueue.RetryConstraint) TargetApi(android.annotation.TargetApi)

Aggregations

JobManagerCallbackAdapter (com.birbit.android.jobqueue.callback.JobManagerCallbackAdapter)12 Job (com.birbit.android.jobqueue.Job)10 DummyJob (com.birbit.android.jobqueue.test.jobs.DummyJob)10 CountDownLatch (java.util.concurrent.CountDownLatch)10 TargetApi (android.annotation.TargetApi)8 JobManager (com.birbit.android.jobqueue.JobManager)8 Params (com.birbit.android.jobqueue.Params)8 Test (org.junit.Test)4 RetryConstraint (com.birbit.android.jobqueue.RetryConstraint)3 Configuration (com.birbit.android.jobqueue.config.Configuration)3 ArrayList (java.util.ArrayList)3 SuppressLint (android.annotation.SuppressLint)1 Pair (android.util.Pair)1 CallbackManager (com.birbit.android.jobqueue.CallbackManager)1 JobStatus (com.birbit.android.jobqueue.JobStatus)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 FutureTask (java.util.concurrent.FutureTask)1 Semaphore (java.util.concurrent.Semaphore)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1