Skip to content

A Dart implementation of p-limit for controlling concurrency of async operations.

License

Notifications You must be signed in to change notification settings

fluttercandies/f_limit

Repository files navigation

๐Ÿšฆ f_limit

pub packageLicense: MIT

A Dart implementation of p-limit for controlling the concurrency of async operations.

ไธญๆ–‡ๆ–‡ๆกฃ | English

โœจ Features

  • ๐Ÿ”ข 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

๐Ÿš€ Quick Start

Installation

Add this to your pubspec.yaml:

dependencies: f_limit: ^1.0.0

Then run:

dart pub get

Basic Usage

import'package:f_limit/f_limit.dart'; voidmain() async{// ๐Ÿ”ง Create a limiter that allows only 2 concurrent operationsfinal limit =fLimit(2); // ๐Ÿ“ Create some async tasksfinal tasks =List.generate(5, (i) => () async{print('๐Ÿš€ Task $i started'); awaitFuture.delayed(Duration(seconds:1)); print('โœ… Task $i completed'); return'Result $i'}); // โšก Execute all tasks with concurrency limitfinal futures = tasks.map((task) =>limit(task)); final results =awaitFuture.wait(futures); print('๐ŸŽ‰ All tasks completed: $results')}

๐Ÿ“š Usage Examples

๐ŸŒ API Rate Limiting

import'package:f_limit/f_limit.dart'; Future<String> fetchData(String url) async{// Simulate API callawaitFuture.delayed(Duration(milliseconds:200)); return'Data from $url'} voidmain() async{// ๐Ÿ›ก๏ธ Limit API calls to 3 concurrent requestsfinal 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 limitingfinal futures = urls.map((url) =>limit(() =>fetchData(url))); final results =awaitFuture.wait(futures); print('๐Ÿ“Š API Results: $results')}

๐ŸŽ›๏ธ Dynamic Concurrency Control

voidmain() async{final limit =fLimit(1); // ๐Ÿ“ Start with limited concurrencyfinal futures =<Future<String>>[]; for (int i =0; i <10; i++){futures.add(limit(() async{print('๐Ÿ”„ Task $i (concurrency: ${limit.concurrency})'); awaitFuture.delayed(Duration(milliseconds:100)); return'Task $i done'}))} // ๐Ÿš€ Increase concurrency after some timeFuture.delayed(Duration(milliseconds:300), (){print('โฌ†๏ธ Increasing concurrency to 5'); limit.concurrency =5}); awaitFuture.wait(futures); print('๐ŸŽ‰ All tasks completed')}

๐Ÿ“‹ Queue Strategies

๐Ÿ”„ FIFO (First In, First Out) - Default

final limit =fLimit(2, queueStrategy:QueueStrategy.fifo); // Tasks execute in the order they were added

๐Ÿ“š LIFO (Last In, First Out)

final limit =fLimit(2, queueStrategy:QueueStrategy.lifo); // Tasks execute in reverse order (stack-like behavior)

โญ Priority Queue

final limit =fLimit(2, queueStrategy:QueueStrategy.priority); // ๐ŸŽฏ Add tasks with different prioritieslimit(() 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)

๐Ÿ† Priority-based Task Management

voidmain() 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)); awaitFuture.wait(futures); // Output: ๐Ÿ”ด ๐ŸŸก ๐ŸŸข }

๐Ÿ“– API Reference

๐Ÿ”ง fLimit(int concurrency,{QueueStrategy queueStrategy})

Creates a concurrency limiter.

Parameters:

  • concurrency - Maximum number of concurrent operations (โ‰ฅ 1)
  • queueStrategy - Queue execution strategy (optional, defaults to FIFO)

Returns:FLimit instance

๐Ÿ“Š QueueStrategy

Queue execution strategies:

StrategyDescriptionUse Case
fifoFirst In, First Out๐Ÿ“‹ Fair task execution
lifoLast In, First Out๐Ÿ“š Stack-like processing
priorityPriority-basedโญ Important tasks first

๐Ÿ—๏ธ FLimit Class

Properties

  • activeCount - ๐Ÿ”„ Number of currently executing operations
  • pendingCount - โณ Number of queued operations
  • concurrency - ๐ŸŽ›๏ธ Current concurrency limit (get/set)
  • queueStrategy - ๐Ÿ“‹ Current queue strategy

Methods

  • call(function,{priority}) - ๐Ÿš€ Execute function with concurrency limit
  • isolate(computation,{priority}) - ๐Ÿงต Execute computation in a separate isolate
  • map(items, mapper) - ๐Ÿ—บ๏ธ Map items concurrently
  • onIdle - ๐Ÿ’ค Wait for idle state
  • clearQueue() - ๐Ÿ—‘๏ธ Clear all pending operations

๐Ÿ”— limitFunction<T>(function, options)

Creates a limited version of a function.

Parameters:

  • function - The function to limit
  • options - LimitOptions with concurrency and queue strategy

Returns: Limited function wrapper

๐Ÿ›ก๏ธ Error Handling

The limiter properly handles errors in async operations:

final limit =fLimit(2); final future1 =limit(() async{throwException('๐Ÿ’ฅ 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 succeedprint('โœ… Result: $result');

๐Ÿงต Isolate Support (Dart 2.19+)

You can run computationally heavy tasks in a separate isolate while respecting the concurrency limit using isolate:

final limit =fLimit(2); // โšก This will run in a separate isolate!final result =await limit.isolate((){// ๐Ÿ”จ Heavy computation hereint sum =0; for (int i =0; i <1000000; i++){sum += i} return sum}); print('Result: $result');

Note: The function passed to isolate must be a static function, a top-level function, or a closure that is sendable (i.e., it doesn't capture any non-sendable objects).

๐Ÿ› ๏ธ Extensions

map

Process items in an iterable concurrently:

final limit =fLimit(2); final items = [1, 2, 3, 4, 5]; // Map items to results with concurrency limitfinal results =await limit.map(items, (item) async{awaitFuture.delayed(Duration(seconds:1)); return item *2});

onIdle

Wait for all tasks to complete:

await limit.onIdle; print('All tasks finished and queue is empty');

๐Ÿ” Monitoring and Debugging

final limit =fLimit(3); // ๐Ÿ“Š Monitor queue statusprint('Active: ${limit.activeCount}'); print('Pending: ${limit.pendingCount}'); print('Strategy: ${limit.queueStrategy}'); // ๐Ÿ”ง Add tasks and monitorfor (int i =0; i <10; i++){limit(() async{print('๐Ÿ“Š Active: ${limit.activeCount}, Pending: ${limit.pendingCount}'); awaitFuture.delayed(Duration(milliseconds:100))})}

๐Ÿ†š Comparison with JavaScript p-limit

JavaScriptDartDescription
const limit = pLimit(2)final limit = fLimit(2)๐Ÿ”ง Create limiter
limit(() => asyncTask())limit(() => asyncTask())๐Ÿš€ Execute task
limit.activeCountlimit.activeCount๐Ÿ“Š Active count
limit.pendingCountlimit.pendingCountโณ Pending count
limit.clearQueue()limit.clearQueue()๐Ÿ—‘๏ธ Clear queue

๐ŸŽฏ Advanced Examples

๐Ÿ“ File Processing with Priority

enumTaskPriority{low(1), medium(5), high(10); constTaskPriority(this.value); finalint value} Future<void> processFiles() async{final limit =fLimit(3, queueStrategy:QueueStrategy.priority); // ๐Ÿ”ด Critical system fileslimit(() =>processFile('system.log'), priority:TaskPriority.high.value); // ๐ŸŸก User documents limit(() =>processFile('document.pdf'), priority:TaskPriority.medium.value); // ๐ŸŸข Cache fileslimit(() =>processFile('cache.tmp'), priority:TaskPriority.low.value)}

๐ŸŒŠ Batch Processing

Future<void> batchProcess(List<String> items) async{final limit =fLimit(5); awaitFuture.wait( items.map((item) =>limit(() =>processItem(item))) ); print('๐ŸŽ‰ Batch processing completed!')}

๐Ÿค Contributing

We welcome contributions!

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ™ Acknowledgements


๐Ÿ  FlutterCandies | ๐Ÿ“ฆ pub.dev | ๐Ÿ› Issues

Made with โค๏ธ by the FlutterCandies team

About

A Dart implementation of p-limit for controlling concurrency of async operations.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages