Chuyển sang không gian làm việc lớn hơn mà không ai phải chờ
Mỗi dự án Mythex có một không gian làm việc riêng: một máy tính đám mây nhỏ, nơi agent viết code và bản xem trước của app chạy. Chúng tôi đã nâng bộ nhớ của không gian làm việc mới từ 1 GB lên 2 GB, nhưng các không gian cũ vẫn ở mức 1 GB. Vào ngày chúng tôi kiểm tra, khoảng một phần tư trong số đó vẫn như vậy. Bản sửa đầu tiên chuyển một dự án sang không gian lớn hơn khi nó được mở lại. Ngay ngày đầu tiên chạy trên production, nó khiến một người phải chờ bảy phút. Chúng tôi đặt giới hạn thời gian cứng cho việc này, rồi sau đó gỡ việc chuyển đổi ra khỏi thao tác mở dự án.
Vì sao các không gian cũ vẫn nhỏ
Nhà cung cấp sandbox của chúng tôi đặt kích thước của một không gian làm việc khi nó được tạo, và giữ nguyên kích thước đó qua mọi lần tạm dừng và tiếp tục. Thay đổi template, tức là công thức mà các không gian mới được xây dựng từ đó, chỉ ảnh hưởng đến các không gian được tạo sau thay đổi. Không có gì thay đổi kích thước những không gian đã tồn tại.
Điều đó quan trọng. Một trong các không gian nhỏ đã hết bộ nhớ trong lúc git push khi bản xem trước của nó đang khởi động, và ngừng phản hồi trong 11 phút. Một lần publish thất bại vì vậy.
Lần thử đầu: chuyển dự án khi nó được đánh thức
Không gian làm việc tạm dừng khi không ai dùng và được đánh thức khi dự án được mở. Lúc đánh thức có vẻ là thời điểm hợp lý để chuyển dự án, vì chưa ai làm việc trong đó.
Quá trình chuyển đổi hoạt động như sau:
- Kiểm tra kích thước. Nếu không gian nhỏ hơn 2 GB, chuyển đi. Nếu không biết kích thước, không làm gì.
- Không làm gián đoạn một lần publish. Một lần publish đọc các file trong không gian làm việc, nên nếu có lần publish đang chạy, bỏ qua việc chuyển.
- Đóng gói dự án. Nén mọi thứ trong dự án, bao gồm lịch sử git (tức là mọi checkpoint của dự án) và file
.envcủa app, thuộc về chủ app. Nhưng bỏ qua các dependency đã cài (node_modules), vì chúng có thể cài lại. - Sao chép thẳng sang. Truyền luồng gói nén từ không gian cũ sang một không gian 2 GB mới, để nó không bao giờ phải nằm trọn trong bộ nhớ của server chúng tôi.
- So sánh trước khi chuyển. Đếm số file, đọc checkpoint mới nhất, và đếm số checkpoint, ở cả hai không gian. Chỉ chuyển khi cả ba khớp nhau.
- Giữ không gian cũ nếu có bất kỳ lỗi nào. Bất kỳ lỗi nào hoặc sai khác nào sẽ hủy không gian mới và mở dự án trong không gian cũ, như trước đây.
Một chi tiết trong bước so sánh quan trọng hơn vẻ ngoài của nó. Việc kiểm tra chạy dưới tài khoản quản trị, và git từ chối đọc một repository thuộc sở hữu của người dùng khác. Nó không in ra gì ở cả hai bên, và “không có gì” khớp với “không có gì”, nên kiểm tra vẫn qua mà không hề so sánh lịch sử nào. Chúng tôi đã cấu hình git tin tưởng thư mục đó, và thêm một test để lỗi này không quay lại.
Chuyện gì xảy ra vào ngày đầu tiên
Ngày đầu tiên chạy trên production, việc đóng gói một dự án đã chạm đến giới hạn lệnh năm phút, ngay trong lúc đánh thức. Chủ dự án phải chờ bảy phút để không gian làm việc của họ mở ra. Và vì việc chuyển đổi thất bại, dự án vẫn ở kích thước nhỏ, nên lần mở tiếp theo sẽ thử lại và bắt họ chờ thêm lần nữa.
Một quá trình di chuyển khiến người ta phải chờ khi mở dự án của chính họ là một sự đánh đổi tệ. Lý do của việc làm nó khi đánh thức là để không ai nhận ra.
Lần thử thứ hai: một ngân sách thời gian cứng
Cùng ngày đó, chúng tôi thay đổi bốn điều:
- Một phút cho toàn bộ quá trình chuyển. Mọi bước (kiểm tra kích thước, đóng gói, tạo không gian mới, sao chép, giải nén, so sánh) dùng chung một ngân sách 60 giây. Khi hết, dự án mở trong không gian cũ.
- Dừng công việc, không chỉ dừng việc chờ. Việc bỏ cuộc phía chúng tôi là chưa đủ nếu việc nén vẫn đang chạy bên trong không gian mà chủ dự án sắp dùng. Giờ mỗi lệnh nén bị dừng ngay bên trong không gian làm việc, ngay trước khi ngân sách kết thúc. Nếu không gian mới đến sau khi chúng tôi đã bỏ cuộc, nó sẽ bị hủy.
- Không để chủ dự án chờ việc dọn dẹp. Việc xóa file nén tạm giờ diễn ra ở nền.
- Không thử lại ở mọi lần mở. Một dự án không thể chuyển sẽ bị bỏ qua trong 24 giờ, nên một lần thất bại chỉ gây trễ nhiều nhất một lần mỗi ngày, chứ không phải mỗi lần mở.
Lần thử thứ ba: đưa việc chuyển đổi ra khỏi lúc đánh thức
Như vậy trường hợp xấu nhất chỉ còn một phút. Nhưng một phút vẫn là một phút, và chúng tôi nhận ra việc chuyển đổi không cần nằm trên đường đi của bất kỳ ai.
Giờ không còn không gian nào được tạo ở mức 1 GB nữa. Vì vậy đây không phải một tiến trình liên tục; nó là một công việc một lần với danh sách cố định các không gian. Làm việc này bên trong lúc đánh thức nghĩa là một người thật phải trả giá cho mỗi lần chuyển chậm, và cách duy nhất để biết một không gian không chuyển được là có người vừa phải chờ nó.
Vì thế chúng tôi gỡ việc chuyển đổi ra khỏi lúc đánh thức hoàn toàn. Việc mở dự án vẫn làm như trước. Những không gian nhỏ còn lại được xử lý như một đợt có giám sát: không ai đang chờ, và một không gian không chuyển được sẽ hiện trong báo cáo của đợt đó, để chúng tôi xem xét, thay vì xuất hiện trước mặt chủ sở hữu của nó.
Điều chúng tôi rút ra
- Không phải lúc nào cũng có thể thay đổi kích thước. Khi nền tảng cố định kích thước lúc tạo, việc tăng mặc định chỉ giúp những thứ mới. Hãy lên kế hoạch cho những thứ cũ.
- “Chưa ai dùng” vẫn nghĩa là có người đang chờ. Công việc làm trên đường đi vào một sản phẩm là công việc mà một người đang quan sát.
- Đặt ngân sách cho mọi thứ nằm trên đường đi của người dùng, và dừng công việc khi hết ngân sách. Hết thời gian chờ phía chúng tôi trong khi một lệnh vẫn chạy ở nơi khác chỉ làm vấn đề dịch chuyển đi.
- Một quá trình di chuyển một lần thuộc về một job một lần. Giấu nó vào các thao tác hằng ngày làm nó rẻ hơn để viết nhưng đắt hơn để vận hành.
- Kiểm thử các kiểm tra an toàn của bạn. Một phép so sánh không so sánh gì trông y hệt một phép so sánh đã đạt.
Nếu bạn đang xây dựng trên Mythex, không cần làm gì cả: mục tiêu chỉ là ít không gian làm việc hết bộ nhớ hơn, và việc mở dự án vẫn nhanh như trước. Cách không gian làm việc tạm dừng và được đánh thức được mô tả trong tài liệu, tại mục private workspace. Về một câu chuyện hết bộ nhớ khác, xem lỗi hết bộ nhớ ẩn trong một nhãn tiến trình.