Tôi nhìn thấy một hành vi rất kỳ lạ nơi Haskell của bracket
chức năng là hành xử khác nhau tùy thuộc vào việc stack run
hay stack test
được sử dụng.
Hãy xem xét đoạn mã sau, trong đó hai dấu ngoặc lồng được sử dụng để tạo và dọn sạch các container Docker:
module Main where
import Control.Concurrent
import Control.Exception
import System.Process
main :: IO ()
main = do
bracket (callProcess "docker" ["run", "-d", "--name", "container1", "registry:2"])
(\() -> do
putStrLn "Outer release"
callProcess "docker" ["rm", "-f", "container1"]
putStrLn "Done with outer release"
)
(\() -> do
bracket (callProcess "docker" ["run", "-d", "--name", "container2", "registry:2"])
(\() -> do
putStrLn "Inner release"
callProcess "docker" ["rm", "-f", "container2"]
putStrLn "Done with inner release"
)
(\() -> do
putStrLn "Inside both brackets, sleeping!"
threadDelay 300000000
)
)
Khi tôi chạy cái này stack run
và ngắt với Ctrl+C
, tôi nhận được kết quả mong đợi:
Inside both brackets, sleeping!
^CInner release
container2
Done with inner release
Outer release
container1
Done with outer release
Và tôi có thể xác minh rằng cả hai container Docker được tạo và sau đó loại bỏ.
Tuy nhiên, nếu tôi dán chính xác mã này vào một bài kiểm tra và chạy stack test
, chỉ (một phần) lần dọn dẹp đầu tiên xảy ra:
Inside both brackets, sleeping!
^CInner release
container2
Điều này dẫn đến một container Docker còn chạy trên máy của tôi. Chuyện gì đang xảy ra vậy?
- Tôi đã chắc chắn rằng chính xác như vậy
ghc-options
được truyền cho cả hai. - Repo trình diễn đầy đủ ở đây: https://github.com/thomasjm/bracket- phát hành
.stack-work
và chạy trực tiếp, thì vấn đề sẽ không xảy ra. Nó chỉ xảy ra khi chạy dưới stack test
.
stack test
bắt đầu các luồng công nhân để xử lý các bài kiểm tra. 2) trình xử lý SIGINT giết chết luồng chính. 3) Các chương trình Haskell chấm dứt khi luồng chính thực hiện, bỏ qua mọi luồng bổ sung. 2 là hành vi mặc định trên SIGINT cho các chương trình được biên soạn bởi GHC. 3 là cách các chủ đề hoạt động trong Haskell. 1 là một phỏng đoán hoàn chỉnh.