TF-1821 Add Task and WorkerQueue object
(cherry picked from commit 42a90ce7c6bf773416db9a215e0a4c8b348c85ff)
This commit is contained in:
@@ -0,0 +1,44 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:tmail_ui_user/features/offline_mode/worker/hive_task_state.dart';
|
||||||
|
|
||||||
|
class HiveTask<A> with EquatableMixin {
|
||||||
|
final String? id;
|
||||||
|
final A? action;
|
||||||
|
final Future<bool> Function()? conditionInvoked;
|
||||||
|
final Future Function() runnable;
|
||||||
|
|
||||||
|
HiveTask({
|
||||||
|
required this.runnable,
|
||||||
|
this.id,
|
||||||
|
this.action,
|
||||||
|
this.conditionInvoked,
|
||||||
|
});
|
||||||
|
|
||||||
|
Future execute() async {
|
||||||
|
final resultCompleter = Completer();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (conditionInvoked != null) {
|
||||||
|
final invoked = await conditionInvoked!.call();
|
||||||
|
if (invoked) {
|
||||||
|
final result = await runnable.call();
|
||||||
|
resultCompleter.complete(TaskSuccess(result: result));
|
||||||
|
} else {
|
||||||
|
resultCompleter.completeError(TaskFailure());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final result = await runnable.call();
|
||||||
|
resultCompleter.complete(TaskSuccess(result: result));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
resultCompleter.completeError(TaskFailure(exception: e));
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultCompleter.future;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [runnable, id, action, conditionInvoked];
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import 'package:core/presentation/state/failure.dart';
|
||||||
|
import 'package:core/presentation/state/success.dart';
|
||||||
|
|
||||||
|
class TaskSuccess extends Success {
|
||||||
|
final dynamic result;
|
||||||
|
|
||||||
|
TaskSuccess({this.result});
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [result];
|
||||||
|
}
|
||||||
|
|
||||||
|
class TaskFailure extends Failure {
|
||||||
|
final dynamic exception;
|
||||||
|
|
||||||
|
TaskFailure({this.exception});
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [exception];
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:collection';
|
||||||
|
|
||||||
|
import 'package:core/utils/app_logger.dart';
|
||||||
|
import 'package:tmail_ui_user/features/offline_mode/worker/hive_task.dart';
|
||||||
|
|
||||||
|
abstract class WorkerQueue<A> {
|
||||||
|
|
||||||
|
final Queue<HiveTask<A>> queue = Queue<HiveTask<A>>();
|
||||||
|
Completer? completer;
|
||||||
|
|
||||||
|
String get workerName;
|
||||||
|
|
||||||
|
Future addTask(HiveTask<A> task) {
|
||||||
|
queue.add(task);
|
||||||
|
log('WorkerQueue<$workerName>::addTask(): QUEUE_LENGTH: ${queue.length}');
|
||||||
|
return _processTask();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future _processTask() async {
|
||||||
|
if (completer != null) {
|
||||||
|
return completer!.future;
|
||||||
|
}
|
||||||
|
completer = Completer();
|
||||||
|
if (queue.isNotEmpty) {
|
||||||
|
final firstTask = queue.removeFirst();
|
||||||
|
log('WorkerQueue<$workerName>::_processTask(): ${firstTask.id}');
|
||||||
|
firstTask.execute()
|
||||||
|
.then(_handleTaskExecuteCompleted)
|
||||||
|
.catchError(_handleTaskExecuteError);
|
||||||
|
} else {
|
||||||
|
completer?.complete();
|
||||||
|
}
|
||||||
|
return completer!.future;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handleTaskExecuteCompleted(dynamic value) {
|
||||||
|
log('WorkerQueue<$workerName>::_handleTaskExecuteCompleted(): $value');
|
||||||
|
completer?.complete();
|
||||||
|
_releaseCompleter();
|
||||||
|
if (queue.isNotEmpty) {
|
||||||
|
_processTask();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handleTaskExecuteError(error) {
|
||||||
|
log('WorkerQueue<$workerName>::_handleTaskExecuteError(): $error');
|
||||||
|
completer?.complete();
|
||||||
|
_releaseCompleter();
|
||||||
|
if (queue.isNotEmpty) {
|
||||||
|
_processTask();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _releaseCompleter() {
|
||||||
|
completer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future release() async {
|
||||||
|
log('WorkerQueue<$workerName>::release():');
|
||||||
|
queue.clear();
|
||||||
|
_releaseCompleter();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user