Ngăn Mac ngủ khi đang build Xcode hoặc cargo kéo dài

Cách nhanh và miễn phí là dùng caffeinate: chạy caffeinate -i cargo build --release (thay bằng lệnh build của riêng bạn) và macOS sẽ không ngủ do rảnh tay cho đến khi tiến trình đó kết thúc, không cần cài thêm app nào. Một cờ đó giải quyết được chuyện bị ngắt quãng, nhưng không giải quyết câu hỏi về an toàn, vì caffeinate không hề biết Mac có đang quá nóng hay sắp cạn pin trong lúc nó giữ khóa. Dưới đây là cách chặn Mac ngủ trong khi build theo hướng miễn phí, chỗ mà cách miễn phí đó hết tác dụng với một build native kéo dài, và hai cách LidRun hiểu đúng tiến trình build để tự động giữ Mac thức, rồi để nó ngủ lại ngay khi build xong hoặc khi phần cứng cần nghỉ.
Vì sao build bị gián đoạn khi bạn rời máy
Bộ đếm giờ ngủ do rảnh tay không biết build là gì. Nó chỉ theo dõi thao tác bàn phím/chuột và màn hình, chứ không biết clang có đang biên dịch dở một translation unit hay không. Một build cargo chạy 40 phút mà không có phím nào được gõ trông y hệt một máy đang rảnh, nên macOS làm đúng phận sự của nó: cho máy ngủ.
Khi máy ngủ giữa chừng, công việc dừng lại đúng tại chỗ nó đang đứng. Không có gì bị hỏng, nhưng trình biên dịch bị đóng băng, và bất kỳ cache incremental nào đang được làm nóng cũng ngừng lại. Bạn đánh thức Mac, build tiếp tục hoặc chạy lại từ đầu, và khoảng chờ mà bạn tưởng sắp xong lại bắt đầu lại.
Khó chịu nhất là với những tác vụ dài và im lìm: một lần archive Xcode toàn bộ, cài node_modules từ đầu, hay một build cargo release bật tối ưu hóa. Chính những build mà bạn muốn khởi chạy rồi bỏ đó đi làm việc khác lại là những build dễ bị bộ đếm giờ ngủ cắt ngang nhất.
Cách khắc phục miễn phí: bọc build trong caffeinate
Trước khi tìm đến bất kỳ app nào, hãy thử công cụ đã có sẵn trên Mac. caffeinate là tiện ích dòng lệnh của chính Apple để giữ các power-management assertion, và nó có thể bọc trực tiếp một lệnh: caffeinate -i cargo build --release giữ một assertion chống ngủ do rảnh tay đúng bằng thời gian tiến trình đó chạy, rồi giải phóng ngay khi tiến trình kết thúc. Thay bằng lệnh của riêng bạn: caffeinate -i npm run build, caffeinate -i xcodebuild -scheme MyApp -configuration Release build, caffeinate -i make all.
Cờ -i mới là cái quan trọng ở đây (ngăn ngủ do rảnh tay); -d thì giữ luôn màn hình sáng nếu bạn muốn ngồi nhìn output chạy qua, còn -w <pid> cho phép bạn gắn caffeinate vào một tiến trình đang chạy sẵn thay vì phải tự khởi chạy nó. Với một build đơn lẻ, chạy một lần trên chiếc máy bạn đang ngồi trước mặt, đây là câu trả lời hoàn toàn hợp lý, không cần cài gì thêm, và tự thân nó đã đáng để biết.
Với nhiều người, đây thực sự là bước đầu tiên đúng đắn. Phần còn lại của bài này nói về chỗ nó không còn đủ nữa, và một thiết lập hiểu đúng tiến trình build, có kiểm tra an toàn, trông như thế nào khi đến lúc đó.
Hướng dẫn liên quanGiữ Mac thức chỉ khi nó thực sự đang chạy việcChỗ cách miễn phí hết tác dụng
caffeinate không hề biết Mac đang ở trạng thái nào. Nó giữ cùng một assertion chống ngủ do rảnh tay dù pin còn 8% trên một laptop đang nóng hay còn 90% trên bàn có luồng khí lưu thông tốt, vì nó không đọc bất kỳ tín hiệu nào trong hai thứ đó — nó là một wake lock, không phải lưới an toàn. Để một build release dài chạy không người trông dưới caffeinate, và sẽ chẳng có gì theo dõi pin hay nhiệt độ thay bạn.
Nó cũng chỉ gắn với đúng tiến trình bạn bọc, đây là điểm mạnh cho đến khi nó trở thành lỗ hổng. Đóng tab terminal, mất kết nối SSH, hay để job shell bị SIGHUP, assertion có thể chết theo trừ khi bạn nhớ dùng nohup hoặc disown, và thế là bạn quay lại tình trạng không được bảo vệ trên một build mà bạn tưởng đã yên tâm.
Phiên bản của vấn đề này khi gập nắp lại là một công cụ hoàn toàn khác: pmset -a disablesleep 1 là cờ chặn Mac ngủ khi đóng nắp (đúng cờ mà chế độ clamshell của LidRun dùng bên dưới, luôn đi kèm một disablesleep 0 tương ứng khi tắt). Tự tay chạy nó cho một build đóng nắp rồi quên bật lại, và mọi lần đóng nắp sau này trên chiếc Mac đó sẽ không ngủ nữa cho đến khi bạn nhớ ra — một cái bẫy thật sự cho thứ vốn chỉ định dùng một lần.
Các công cụ trên menu-bar như Amphetamine, KeepingYouAwake, Lungo, và Caffeine giải quyết vấn đề hay quên bằng giao diện dễ chịu hơn so với việc gõ cờ dòng lệnh. Amphetamine đặc biệt có thể kích hoạt theo một app đang chạy thay vì phải bật tay, và có cả trigger theo mức pin để kết thúc phiên, cả hai đều thực sự hữu ích. Điều mà không công cụ nào trong số đó làm, theo như các tính năng họ công bố, là kết hợp việc đó với áp lực nhiệt theo thời gian thực, theo cách một ngưỡng auto-stop dựa trên cả pin lẫn nhiệt độ làm được. Chúng giữ khóa theo lịch hoặc trigger bạn đặt, còn việc biết khi nào nên buông ra vẫn là chuyện của bạn.
Hai cách LidRun hiểu đúng tiến trình build để giữ máy thức
Lời hứa nền tảng của LidRun rất đơn giản: agent hay build đang chạy thì giữ máy thức; build xong hoặc Mac không còn an toàn thì buông ra và để máy ngủ. Có hai cách để làm điều đó với một build native.
Cách đầu tiên là hoàn toàn tự động. Auto Mode theo dõi các dev tool bạn khai báo, theo tên tiến trình, hoặc theo command line với các interpreter như node và python, và giữ Mac thức trong khi chúng thực sự đang làm việc. cargo, xcodebuild, swift, swiftc, npm, node, pnpm, yarn, make, cmake, ninja, gradle, mvn, và dotnet đều đã có sẵn trong danh sách theo dõi mặc định, không cần thêm gì với một toolchain tiêu chuẩn. Một tiến trình chỉ được tính là đang hoạt động khi CPU của nó vượt một ngưỡng (mặc định 5%, có thể chỉnh), nên một Terminal đang rảnh không giữ Mac thức, còn một trình biên dịch ghim chặt một nhân CPU thì có. Một khoảng holdoff, mặc định 60 giây và chỉnh được từ 10 đến 600, giữ assertion sống qua mẫu bận cuối cùng, để một khoảng lặng ngắn giữa các giai đoạn build không làm rớt khóa.
Cách thứ hai là tường minh: bọc build bằng lidrun -- <lệnh build của bạn> và LidRun giữ một assertion keep-awake đúng bằng vòng đời của lệnh đó, rồi giải phóng ngay khi lệnh kết thúc. Exit code của chính lệnh đó trở thành exit code của lidrun, nên $? (hoặc if lidrun -- npm run build; then … trong một script) sẽ cho bạn biết build có pass hay không. LidRun tự nó không in ra thời lượng chạy, nên hãy pipe qua time nếu bạn muốn biết: time lidrun -- cargo build --release.
Auto Mode phù hợp hơn khi build đến rồi đi suốt ngày trên nhiều dự án khác nhau; wrapper phù hợp hơn khi bạn có đúng một lệnh dài cụ thể cần trông chừng, hoặc một script kiểu CI. Cả hai đều là tính năng Pro, không nằm trong gói miễn phí — nút Keep Awake thuần (bật/tắt thủ công, miễn phí vĩnh viễn) đã mang sẵn cùng cơ chế giám sát an toàn về pin và nhiệt độ được mô tả bên dưới, chỉ là nó không tự phát hiện build giúp bạn.
Cơ chế giám sát an toàn vẫn luôn áp dụng
Giữ Mac thức cho một build dài là phần dễ. Làm điều đó mà không âm thầm hầm nóng pin hay vỏ máy mới là phần đáng để làm cho đúng, và đó là lý do LidRun không chỉ tắt sleep rồi bỏ đó, dù bạn dùng chế độ nào trong hai chế độ trên.
Pin: một ngưỡng auto-stop, mặc định 20% và chỉnh được từ 15% đến 50%, dừng việc giữ máy thức ngay khi mức pin tụt xuống dưới đó, từ đó Mac được tự do ngủ bình thường thay vì tiếp tục cạn dần về 0. Nhiệt độ: LidRun theo dõi áp lực nhiệt từ chính tín hiệu của SoC, chứ không chỉ dựa vào chỉ số thô ở cấp hệ điều hành, và khi gặp mức đọc nguy cấp, Safety Governor lập tức buông khóa keep-awake ra; nếu bạn cũng bật tùy chọn "ngủ khi quá nhiệt", nó có thể leo thang lên mức thực sự cho Mac đi ngủ thay vì chỉ buông khóa. Điều này giúp giảm rủi ro, chứ không khiến việc quá nhiệt trở nên bất khả thi — luồng khí lưu thông và vị trí bạn đặt laptop vẫn là trách nhiệm của bạn.
Mỗi quyết định như vậy đều được ghi vào Activity Log kèm lý do — một mục auto-stop vì pin sẽ nêu rõ mức phần trăm đã kích hoạt, một mục vì nhiệt độ nghĩa là Safety Governor đã lùi lại — nên nếu một build dài bị cắt ngang, bạn có thể thấy vì sao thay vì phải đoán. Cuốn nhật ký đó là cái giá trung thực để đổi lấy việc không phải là một wake lock mù quáng.
Thiết lập cho các build hằng ngày
Auto Mode: nhấp vào biểu tượng LidRun trên menu-bar rồi bật Auto Mode lên. Với một toolchain Xcode, npm, hay cargo thông thường thì chẳng cần cấu hình gì cả, các công cụ đó đã có sẵn trong danh sách theo dõi mặc định. Các subtool rộng hơn của Apple như clang và swift-frontend lại chạy trong rất nhiều việc không liên quan, nên chúng mặc định tắt, ở dạng chip opt-in thay vì được tự động theo dõi — chỉ bật lên nếu bạn thực sự muốn LidRun phản ứng theo chúng.
CLI wrapper: cài lệnh lidrun một lần từ menu (nó ghi một script wrapper nhỏ vào /usr/local/bin/lidrun), rồi chạy build của bạn qua đó: lidrun -- cargo build --release, lidrun -- xcodebuild -scheme MyApp build, lidrun -- npm run build. Với một lệnh nối chuỗi, hãy đặt cả cụm trong một đối số duy nhất, lidrun -- 'npm ci && npm run build', nếu không shell sẽ tách theo && trước khi lidrun kịp thấy gì, và chỉ nửa đầu được bảo vệ. Dù dùng cách nào, hãy chờ một khoảng đuôi ngắn tương tự nhau — Auto Mode kiểm tra lại các tiến trình đang chạy mỗi 10 giây và giữ máy thức qua khoảng holdoff mặc định 60 giây, nên Mac có thể vẫn thức dưới một phút sau khi build đã thực sự xong. Đó là hành vi được thiết kế như vậy, không phải lỗi.
Nếu một build bị cắt ngang, hãy mở Activity Log trước rồi hẵng chạy lại, đừng chạy lại mù quáng — mục ghi sẽ nêu rõ đó là do chạm sàn pin hay do lùi vì nhiệt độ, và bạn có thể nâng ngưỡng pin lên hoặc cải thiện luồng khí lưu thông cho phù hợp. Timer mode (các mốc cố định từ 30 phút đến 8 giờ) là một công cụ khác cho một việc khác, hữu ích khi bạn biết chính xác một việc nên chạy trong bao lâu; còn với một build mà bạn không biết trước độ dài, Auto Mode hay wrapper phù hợp hơn vì chúng kết thúc khi công việc kết thúc, chứ không theo một đồng hồ mà bạn phải đoán đúng.
Hai thói quen quan trọng bất kể bạn dùng chế độ nào: chạy các tác vụ nặng nhất — một clean build toàn bộ, một lượt LTO lớn — trên một mặt phẳng cứng, có luồng khí lưu thông bên dưới, và cắm sạc nếu có thể, vì một laptop chạy pin vẫn phải tôn trọng ngưỡng sàn auto-stop, còn dùng nguồn điện lưới thì loại bỏ hẳn câu hỏi đó. Nếu build của bạn chạy bên trong container, vấn đề ngủ do rảnh tay tương tự cũng xảy ra ở đó — trường hợp build Docker được nói riêng ở một bài khác vì tiến trình mà LidRun cần theo dõi là khác.
LidRun giữ công việc của bạn chạy tiếp khi đóng nắp, với cơ chế bảo vệ pin và nhiệt tích hợp sẵn.
Đã có LidRun? Đọc hướng dẫn thiết lập →
Mới biết đến LidRun? Xem bảng giá →
Câu hỏi thường gặp
Không. Với lidrun -- <lệnh>, assertion được giải phóng ngay khi lệnh kết thúc. Trong Auto Mode, một khi không còn tiến trình nào đang theo dõi bận trên ngưỡng CPU (qua khỏi holdoff, mặc định 60 giây), LidRun sẽ để Mac ngủ lại.
Có. cargo, xcodebuild, swift, swiftc, npm, node, pnpm, yarn, make, cmake, ninja, gradle, mvn, và dotnet đều đã có sẵn trong danh sách theo dõi mặc định. Một tiến trình chỉ được tính là đang hoạt động khi CPU của nó vượt một ngưỡng nhất định, nên một shell đang rảnh không giữ Mac thức, còn một lần compile thật sự thì có.
caffeinate làm đúng công việc cốt lõi đó — giữ một assertion chống ngủ do rảnh tay trong suốt vòng đời của lệnh, miễn phí — và với một build đơn lẻ chạy một lần thì đó là lựa chọn hoàn toàn hợp lý. LidRun thêm vào khả năng tự phát hiện (bạn không phải gõ lại wrapper mỗi lần), một cơ chế auto-stop theo pin và nhiệt độ thay vì giữ máy thức một cách mù quáng, và một mục Activity Log giải thích vì sao một phiên kết thúc.
Khi gặp mức đọc nhiệt độ nguy cấp, Safety Governor lập tức buông khóa keep-awake và ghi lại vào log; nếu bật tùy chọn "ngủ khi quá nhiệt", nó có thể leo thang lên mức cho Mac đi ngủ luôn. Điều này giúp giảm rủi ro, nhưng không thể đảm bảo Mac không bao giờ quá nóng — vị trí đặt máy và luồng khí lưu thông vẫn là trách nhiệm của bạn.
Có, trong giới hạn ngưỡng auto-stop bạn đặt (mặc định 20%, chỉnh được từ 15% đến 50%). Khi mức pin tụt xuống dưới đó, LidRun kết thúc phiên một cách gọn gàng thay vì để pin cạn dần về 0. Với những build nặng nhất, cắm sạc vẫn là lựa chọn an toàn hơn.
Auto Mode và CLI wrapper là các tính năng Pro. Các chế độ thủ công Keep Awake, Timer, và Charging-only miễn phí vĩnh viễn và đã chạy sẵn cùng cơ chế giám sát an toàn về pin và nhiệt độ, chỉ khác là bạn tự bật/tắt chúng thay vì để LidRun tự phát hiện build.