A Dart implementation of p-limit for controlling the concurrency of async operations.
δΈζζζ‘£ | English
- π’ Concurrency Control - Limit the number of concurrent async operations
- ποΈ Dynamic Adjustment - Change concurrency limits on the fly
- π Queue Management - Track active and pending operations
- π Multiple Queue Strategies - FIFO, LIFO, and Priority-based execution
- β‘ High Performance - Efficient queue implementations
- π‘οΈ Error Handling - Proper error propagation and handling
- π¦ Easy to Use - Simple and intuitive API
- π― Type Safe - Full Dart type safety support
Add this to your pubspec.yaml
:
dependencies:
f_limit: ^1.0.0
Then run:
dart pub get
import 'package:f_limit/f_limit.dart';
void main() async {
// π§ Create a limiter that allows only 2 concurrent operations
final limit = fLimit(2);
// π Create some async tasks
final tasks = List.generate(5, (i) => () async {
print('π Task $i started');
await Future.delayed(Duration(seconds: 1));
print('β
Task $i completed');
return 'Result $i';
});
// β‘ Execute all tasks with concurrency limit
final futures = tasks.map((task) => limit(task));
final results = await Future.wait(futures);
print('π All tasks completed: $results');
}
import 'package:f_limit/f_limit.dart';
Future<String> fetchData(String url) async {
// Simulate API call
await Future.delayed(Duration(milliseconds: 200));
return 'Data from $url';
}
void main() async {
// π‘οΈ Limit API calls to 3 concurrent requests
final limit = fLimit(3);
final urls = [
'https://api.example.com/users',
'https://api.example.com/posts',
'https://api.example.com/comments',
'https://api.example.com/albums',
'https://api.example.com/photos',
];
// π Execute API calls with rate limiting
final futures = urls.map((url) => limit(() => fetchData(url)));
final results = await Future.wait(futures);
print('π API Results: $results');
}
void main() async {
final limit = fLimit(1);
// π Start with limited concurrency
final futures = <Future<String>>[];
for (int i = 0; i < 10; i++) {
futures.add(limit(() async {
print('π Task $i (concurrency: ${limit.concurrency})');
await Future.delayed(Duration(milliseconds: 100));
return 'Task $i done';
}));
}
// π Increase concurrency after some time
Future.delayed(Duration(milliseconds: 300), () {
print('β¬οΈ Increasing concurrency to 5');
limit.concurrency = 5;
});
await Future.wait(futures);
print('π All tasks completed');
}
final limit = fLimit(2, queueStrategy: QueueStrategy.fifo);
// Tasks execute in the order they were added
final limit = fLimit(2, queueStrategy: QueueStrategy.lifo);
// Tasks execute in reverse order (stack-like behavior)
final limit = fLimit(2, queueStrategy: QueueStrategy.priority);
// π― Add tasks with different priorities
limit(() async {
print('π΅ Background task');
}, priority: 1);
limit(() async {
print('π΄ Critical task');
}, priority: 10);
limit(() async {
print('π‘ Important task');
}, priority: 5);
// β‘ Execution order: Critical (10), Important (5), Background (1)
void main() async {
final limit = fLimit(1, queueStrategy: QueueStrategy.priority);
final futures = <Future<void>>[];
// π’ Low priority
futures.add(limit(() async {
print('π’ Background maintenance');
}, priority: 1));
// π‘ Medium priority
futures.add(limit(() async {
print('π‘ User notification');
}, priority: 5));
// π΄ High priority
futures.add(limit(() async {
print('π΄ Critical security update');
}, priority: 10));
await Future.wait(futures);
// Output: π΄ π‘ π’
}
Creates a concurrency limiter.
Parameters:
concurrency
- Maximum number of concurrent operations (β₯ 1)queueStrategy
- Queue execution strategy (optional, defaults to FIFO)
Returns: FLimit
instance
Queue execution strategies:
Strategy | Description | Use Case |
---|---|---|
fifo |
First In, First Out | π Fair task execution |
lifo |
Last In, First Out | π Stack-like processing |
priority |
Priority-based | β Important tasks first |
activeCount
- π Number of currently executing operationspendingCount
- β³ Number of queued operationsconcurrency
- ποΈ Current concurrency limit (get/set)queueStrategy
- π Current queue strategy
call(function, {priority})
- π Execute function with concurrency limitclearQueue()
- ποΈ Clear all pending operations
Creates a limited version of a function.
Parameters:
function
- The function to limitoptions
-LimitOptions
with concurrency and queue strategy
Returns: Limited function wrapper
The limiter properly handles errors in async operations:
final limit = fLimit(2);
final future1 = limit(() async {
throw Exception('π₯ Something went wrong');
});
final future2 = limit(() async {
return 'β
Success';
});
try {
await future1; // This will throw
} catch (e) {
print('β Caught error: $e');
}
final result = await future2; // This will succeed
print('β
Result: $result');
final limit = fLimit(3);
// π Monitor queue status
print('Active: ${limit.activeCount}');
print('Pending: ${limit.pendingCount}');
print('Strategy: ${limit.queueStrategy}');
// π§ Add tasks and monitor
for (int i = 0; i < 10; i++) {
limit(() async {
print('π Active: ${limit.activeCount}, Pending: ${limit.pendingCount}');
await Future.delayed(Duration(milliseconds: 100));
});
}
JavaScript | Dart | Description |
---|---|---|
const limit = pLimit(2) |
final limit = fLimit(2) |
π§ Create limiter |
limit(() => asyncTask()) |
limit(() => asyncTask()) |
π Execute task |
limit.activeCount |
limit.activeCount |
π Active count |
limit.pendingCount |
limit.pendingCount |
β³ Pending count |
limit.clearQueue() |
limit.clearQueue() |
ποΈ Clear queue |
enum TaskPriority {
low(1),
medium(5),
high(10);
const TaskPriority(this.value);
final int value;
}
Future<void> processFiles() async {
final limit = fLimit(3, queueStrategy: QueueStrategy.priority);
// π΄ Critical system files
limit(() => processFile('system.log'), priority: TaskPriority.high.value);
// π‘ User documents
limit(() => processFile('document.pdf'), priority: TaskPriority.medium.value);
// π’ Cache files
limit(() => processFile('cache.tmp'), priority: TaskPriority.low.value);
}
Future<void> batchProcess(List<String> items) async {
final limit = fLimit(5);
await Future.wait(
items.map((item) => limit(() => processItem(item)))
);
print('π Batch processing completed!');
}
We welcome contributions!
This project is licensed under the MIT License - see the LICENSE file for details.
- Inspired by p-limit by Sindre Sorhus
- Part of the FlutterCandies organization
π FlutterCandies | π¦ pub.dev | π Issues
Made with β€οΈ by the FlutterCandies team