Skip to content

fluttercandies/f_limit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

3 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🚦 f_limit

pub package License: 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';

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');
}

πŸ“š Usage Examples

🌐 API Rate Limiting

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');
}

πŸŽ›οΈ Dynamic Concurrency Control

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');
}

πŸ“‹ 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 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)

πŸ† Priority-based Task Management

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: πŸ”΄ 🟑 🟒
}

πŸ“– 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:

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

πŸ—οΈ 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
  • 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 {
  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');

πŸ” Monitoring and Debugging

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));
  });
}

πŸ†š Comparison with JavaScript p-limit

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

🎯 Advanced Examples

πŸ“ File Processing with Priority

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);
}

🌊 Batch Processing

Future<void> batchProcess(List<String> items) async {
  final limit = fLimit(5);
  
  await Future.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