Этот вопрос является архитектурной проблемой, которую я не смог понять.
У меня есть TaskScheduler, у которого есть такие операции, как start () и stop (). TaskScheduler предназначен быть агностиком, я хочу иметь возможность передавать в него любые «Runnable», «UID» и «Interval», в течение которых должна работать служба. Все это добавляется в хэш-карту, так что если вы попытаетесь передать существующий исполняемый файл с тем же UID, он заменит предыдущий исполняемый файл новой информацией.
Расширением TaskScheduler является MyScheduler, который относится к запросу, который я хочу сделать. В этом примере я делаю несколько запросов профиля каждые 60 секунд. Чтобы отслеживать, какой из запросов профиля является каким, я использую UID в качестве ключа.
Затем я хочу отобразить ответы на уровне приложения от MyScheduler. Вот где у меня проблемы. Я могу только получить ответ от последнего планировщика. Таким образом, если я создам планировщик A и планировщик B, я буду получать обновления только от планировщика B. Аналогично, если я создам планировщик A-C, то я буду получать обновления только от планировщика C.
Я знаю, почему это так, MyScheduler использует последний запрос, который был ему передан. Однако я не знаю хорошей схемы (методологии) для решения этой проблемы.
TaskScheduler класс
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 (это имя временно)
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);
}
});
}
}
}
Попытка достичь этого на уровне приложения
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
}
});