Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

`FileSystem.Lock.aquire` ends in `UnexpectedError ENOENT` when the lock is released while it checks it

Đang mở Phù hợp với người mới
#14 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
78/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
javascript, node.js
Lĩnh vực
operating-systems

Hướng nghiên cứu

Bắt đầu bằng cách xác định handler LockMetaCheck và các vị từ lỗi của FileSystem trong mã nguồn compiler-node. Chạy reproduction được liên kết hoặc các lệnh gren make/node trong khi churn.js liên tục xóa .lock. Được xem là hoàn tất khi một lock biến mất trong thời gian ngắn được thử lại và lần chạy không còn báo UnexpectedError ENOENT, chỉ kết thúc với các kết quả lock acquired hoặc already locked.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Found against: gren 0.6.6, gren-lang/compiler-node 5.0.0, gren-lang/core 7.4.2, gren-lang/node 6.1.3, node 22
Reproduction: https://github.com/gilramir/gren-bug-reports/tree/main/2026-09-16-lock-vanishes-during-metadata

Taking a lock that another process holds only briefly often ends in
UnexpectedError, when it should end with the lock taken or AlreadyLocked.
aquire creates the lock directory; if it exists, it reads its metadata to see
whether the lock is stale. If the other process removes the lock in between,
metadata fails with ENOENT, and the handler that means to retry tests for
the wrong error.

Reproduction

gren.json: a node application with "gren-lang/compiler-node": "5.0.0", "gren-lang/core": "7.4.2", "gren-lang/node": "6.1.3" (indirect "gren-lang/compiler-common": "3.0.0", "gren-lang/url": "6.0.0").

churn.js stands in for another process that holds the lock very briefly:

// Create and remove ./.lock in a tight loop, as another process holding the
// lock very briefly would.
const fs = require("node:fs");
for (;;) {
  try { fs.mkdirSync(".lock"); } catch (e) {}
  try { fs.rmdirSync(".lock"); } catch (e) {}
}

src/Main.gren tries to take the lock 2000 times, without retries, releasing it
whenever it gets it, and counts how each attempt ended:

(source elided here as it's very long)

gren make Main --output=app
node churn.js &
node app

Output (counts vary with timing):

outcome                      count
UnexpectedError ENOENT         953
already locked                 156
lock acquired                  891

Cause

LockMetaCheck { path, attempt, result = Err fsErr } ->
    if FileSystem.errorIsFileExists fsErr then
        -- Lock might have been removed while we asked for metadata
        update fsPerm (Lock { path = fromLockPath path, attempt = attempt + 1 }) model

    else
        UnexpectedError { path = fromLockPath path, error = fsErr }

The comment describes the right recovery, but reading a directory's metadata
never fails with EEXIST, so a lock that has been removed takes the else
branch.

Proposed Fix

The check should be FileSystem.errorIsNoSuchFileOrDirectory

With it, the same program gave 325 already locked and 1675 lock acquired.

Ngôn ngữ chính
JavaScript
Star
2
Fork
3
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Chuẩn bị môi trường

Chúng tôi chưa kiểm tra các tệp thiết lập môi trường của dự án này. Hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của gren-lang/compiler-node

Tất cả issue của gren-lang/compiler-node

Issue tương tự

Thêm issue về JavaScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.