gpt4 book ai didi

Clojure/jetty : Force URL to only be Hit Once at a Time

转载 作者:行者123 更新时间:2023-12-04 23:55:29 25 4
gpt4 key购买 nike

我正在开发 Clojure/Jetty Web 服务。我有一个特殊的 url,我希望一次只处理一个请求。如果请求了 url,在它返回之前,又请求了 url,我想立即返回。所以在更多 core.clj 中,我定义了我的路线,我有这样的东西:

(def work-in-progress (ref false)) 

然后过一段时间
(compojure.core/GET "/myapp/internal/do-work" []
(if @work-in-progress
"Work in Progress please try again later"
(do
(dosync
(ref-set work-in-progress true))
(do-the-work)
(dosync
(ref-set rebuild-in-progress false))
"Job completed Successfully")))

我已经在本地 Jetty 服务器上尝试过这个,但我似乎能够点击 url 两次并使工作翻倍。在线程 Web 服务器环境中,在 Clojure 中实现这一点的好模式/方法是什么?

最佳答案

想象以下 race condition对于问题中提出的解决方案。

  • 线程 A 开始执行处理程序的主体。 @work-in-progressfalse ,所以它进入 do表达。但是,在它设法设置 work-in-progress 的值之前至 true ...
  • 线程 B 开始执行处理程序的主体。 @work-in-progress是假的,所以它进入 do表达。

  • 现在有两个线程正在执行 (do-the-work)同时。那不是我们想要的。

    为防止出现此问题,请检查并在 dosync 中设置 ref 的值。交易。
    (compojure.core/GET "/myapp/internal/do-work" []
    (if (dosync
    (when-not @work-in-progress
    (ref-set work-in-progress true)))
    (try
    (do-the-work)
    "Job completed Successfully"
    (finally
    (dosync
    (ref-set work-in-progress false))))
    "Work in Progress please try again later"))

    在这种情况下,您可能会发现另一个有用的抽象是原子和 compare-and-set! .
    (def work-in-progress (atom false))

    (compojure.core/GET "/myapp/internal/do-work" []
    (if (compare-and-set! work-in-progress false true)
    (try
    (do-the-work)
    "Job completed Successfully"
    (finally
    (reset! work-in-progress false)))
    "Work in Progress please try again later"))

    关于Clojure/jetty : Force URL to only be Hit Once at a Time,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16947882/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com