【问题标题】:How to achieve a limited number of method executions based on elapsed time?如何根据经过的时间实现有限数量的方法执行?
【发布时间】:2021-09-17 19:37:54
【问题描述】:

我想知道是否有类似于每分钟执行限制的框架。

假设我有一个 API,每分钟可以请求 100 次。

如果我在循环中发送一个“hello world”,我会超过这个限制。

例如,像这样的:

ExecutionLimiter executer = ExecutionLimiter(executions: 100, duration: Duration(minutes: 1));

while (true) {
  executer.add(() => print(“hello world“));
}

我找到了包queue,但这只是为了并行化。

感谢您的帮助。

【问题讨论】:

    标签: flutter dart server frameworks backend


    【解决方案1】:

    您可以使用 Timer.periodic 在每个给定时间激活一个方法。

    _timer = Timer.periodic(Duration(milliseconds: 600), (Timer t) {
      // Send single api request every 600 ms
    });
    
    // Stop sending requests
    Future.delayed(const Duration(minutes: 1), () {
      _timer.cancel();
    });
    

    只是不要忘记将其保存在变量中,并在使用完后将其丢弃。

    【讨论】:

    • 您好,谢谢您的回答。我认为这没有按预期工作,因为没有考虑请求数的平均值。例如,如果 60 个请求需要 50 秒才能被请求,并且在下一次迭代期间立即执行 60 个请求,则平均值将超过 100 个请求/分钟。
    • 哦,我明白了。您可以自己计算每个请求之间应该有多少时间,并在 Duration 中使用它。例如,在这里您可以在持续时间中使用 1600 毫秒,然后平均不会超过 100 个请求。现在只发送 1 个请求,而不是在回调正文中发送 100 个请求。我编辑了答案以反映这一点
    • 我编辑了答案
    【解决方案2】:

    感谢Yair Chen 的支持,我创建了一个简短的示例程序,可以在给定的时间跨度内执行 n 次函数。会考虑执行的持续时间。

    import 'dart:async';
    import 'dart:math';
    
    List<Instance> instances = [];
    
    int executionLimit = 10;
    int apiCallLimitInSeconds = 5;
    
    // for test purposes
    int elapsedTime = 0;
    int executedFunctions = 0;
    
    main() {
      Timer.periodic(Duration(seconds: 1), (Timer t) {
        instances.removeWhere((element) => element.isInvalid);
    
        for (int i = 0; instances.length < executionLimit; i++) {
          instances.add(Instance(
              Future.delayed(Duration(milliseconds: Random().nextInt(100)))
                  .then((value) => executedFunctions++)));
        }
        //tests again
        elapsedTime++;
        if (elapsedTime % 5 == 0) {
          print(executedFunctions);
        }
      });
    }
    
    class Instance {
      Future<void> execute;
      bool isInvalid = false;
    
      Instance(this.execute) {
        execute.then((value) => Timer(
            Duration(seconds: apiCallLimitInSeconds), () => isInvalid = true));
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-18
      • 1970-01-01
      • 2021-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多