This question is an architectural problem that I have not been able to figure out.
I have a TaskScheduler that has operations such as start() and stop(). TaskScheduler is intended to be agnostic, I want to be able to pass into it any "Runnable", a "UID" and the "Interval" that the service should run for. This all gets added to a hashmap so that if you try to pass in an existing runnable with the same UID it will replace the previous runnable with the new information.
Extending the TaskScheduler is MyScheduler, which is specific to the request that I want to make. In this example, I am making multiple Profile requests every 60 seconds. To keep track of which profile request is which, I am using UID as a key.
I want to then bubble up the responses to the app level from MyScheduler. This is where I am having issues. I am only able to bubble up the response from the latest scheduler. So if I create Scheduler A and Scheduler B, I will receive updates only from Scheduler B. Simlarly, if I create Scheduler A-C, then I will receive updates only from Scheduler C.
I know why this is, MyScheduler uses the last request that was passed into it. However, I do not know a good pattern (methodology) to resolve this.
TaskScheduler class
public class TaskScheduler {
private static Map<String, SchedulerModel> schedulerModels = new HashMap<>();
TaskScheduler() {}
private ScheduledFuture<?> start(@NotNull final SchedulerModel schedulerModel) {
return schedulerModel.executorService.scheduleWithFixedDelay(schedulerModel.runnable, 0, schedulerModel.interval, TimeUnit.SECONDS);
}
/**
* Method is used to onSchedulerStop executing tasks
*/
private void shutdown(@NotNull SchedulerModel schedulerModel) {
if (schedulerModel.executorService != null) {
schedulerModel.executorService.shutdownNow();
schedulerModel.executorService = null;
}
}
/**
* Method is used to initialize scheduler task and time delays
*
* @param runnable Represents a command that can be executed
* @param interval The time interval for execution of code
*/
void setTask(Runnable runnable, String uid, int interval) {
SchedulerModel schedulerModel = new SchedulerModel();
schedulerModel.executorService = Executors.newSingleThreadScheduledExecutor();
schedulerModel.runnable = runnable;
schedulerModel.interval = interval;
schedulerModels.put(uid, schedulerModel);
}
public void stop(@NotNull String uid) {
if (schedulerModels.get(uid) != null) {
shutdown(schedulerModels.get(uid));
schedulerModels.remove(uid);
} else {
// scheduler id not found
}
}
public void start(@NotNull String uid) {
if (schedulerModels.get(uid) != null) {
start(schedulerModels.get(uid));
} else {
// scheduler id not found
}
}
}
MyScheduler (this name is temporary)
public class MyScheduler extends TaskScheduler {
private final int DEFAULT_SCHEDULER_INTERVAL = 60; // seconds
private ProfileRequest request;
private ApiInterface apiInterface;
private SchedulerInterface schedulerInterface;
public MyScheduler() {}
public void createScheduler(@NotNull ApiInterface apiInterface,
@NotNull ProfileRequest request,
@NotNull SchedulerInterface schedulerInterface) {
this.apiInterface = apiInterface;
this.request = request;
this.schedulerInterface = schedulerInterface;
super.setTask(new SchedulerRunnable(), request.getUid(), DEFAULT_SCHEDULER_INTERVAL);
}
public void start(@NotNull String uid) {
start(uid); // start scheduler
schedulerInterface.onSchedulerStart(uid); // send feedback to callback
}
public void stop(@NotNull String uid) {
stop(uid); // stop scheduler
schedulerInterface.onSchedulerStop(uid); // send feedback to callback
}
private class SchedulerRunnable implements Runnable {
@Override
public void run() {
ApiClient.createBookmark(request, new Callback<Response>() {
@Override
public void onSuccess(@NotNull Response response) {
schedulerInterface.onSuccess(response);
}
@Override
public void onFailure(@NotNull Exception exception) {
schedulerInterface.onFailure(exception);
}
});
}
}
}
Trying to achieve this on app level
mProfileScheduler.createScheduler(apiInterface, request, new SchedulerInterface {
Override
public void onSuccess(Response response) {
// problem so far is that I only get response from latest scheduler
}
Override
public void onFailure(Exception exception) {}
Override
public void onSchedulerStop(String uid) {
// pass back uid so that I know which profile scheduler was stopped
}
Override
public void onSchedulerStart(String uid) {}
// pass back uid so that I know which profile scheduler was started
}
});