2012-05-08 15 views
5

Tôi có một số ứng dụng trong cụm của mình, tôi cần phải bắt đầu một số ứng dụng trên các máy chủ khác nhau. Câu chuyện là cụm Erlang đang chạy, vì vậy mặc dù tôi có tệp tài nguyên .app của tôi cho mỗi ứng dụng cho biết ứng dụng nào nên được bắt đầu trước khi tôi, điều này chỉ hoạt động để tạo tập lệnh khởi động chứ không phải để bắt đầu ứng dụng trong một nút đang chạy.Erlang, cách tải các ứng dụng với các phụ thuộc của chúng

Hiện tại tôi có thói quen tùy chỉnh sử dụng ứng dụng: get_key (Ứng dụng, ứng dụng) để trích xuất các phụ thuộc và bắt đầu chúng một cách riêng biệt trước khi bắt đầu ứng dụng đã cho.

Tôi đã tự hỏi nếu không có cách nào tốt hơn để làm điều này.

Trả lời

1

Khi khởi động ứng dụng bên ngoài tập lệnh khởi động, trước tiên bạn cần phải bắt đầu phụ thuộc. Bạn có thể xây dựng các thông minh để làm điều này vào chính ứng dụng để khi ứng dụng bắt đầu nó sẽ bắt đầu bất kỳ phụ thuộc cần thiết trước khi nó cần chúng.

Một nơi tôi đã xem việc này được thực hiện trong Mochiweb ứng dụng. Giá trị mặc định app templates bao gồm mã để tải phụ thuộc vào khởi động:

-module(some_app). 
-export([start/0, stop/0]). 

ensure_started(App) -> 
    case application:start(App) of 
     ok -> 
      ok; 
     {error, {already_started, App}} -> 
      ok 
    end. 

%% @spec start() -> ok 
%% @doc Start the some_app server. 
start() -> 
    some_app_deps:ensure(), 
    ensure_started(crypto), 
    application:start(some_app). 

%% @spec stop() -> ok 
%% @doc Stop the some_app server. 
stop() -> 
    application:stop(some_app). 
0

Nếu bạn viết ứng dụng của bạn trong phần "nguyên tắc thiết kế OTP", bạn sẽ phải thực hiện tập tin yourappname.app, mà sẽ chứa 'phần ứng dụng. Phần này xác định các ứng dụng khác mà bạn muốn được bắt đầu trước đó. Here được nêu:

ứng dụng

Tất cả các ứng dụng mà phải được bắt đầu trước khi ứng dụng này được bắt đầu. systools sử dụng danh sách này để tạo các tập lệnh khởi động chính xác . Mặc định là [], nhưng lưu ý rằng tất cả các ứng dụng đều có các phụ thuộc đối với ít nhất hạt nhân và stdlib.

Vì vậy, nếu bạn sử dụng bản phát hành, giải pháp phụ thuộc này sẽ được giải quyết bằng systools.

+1

Tôi nghĩ rằng điều này chỉ đảm bảo ứng dụng của bạn không được bắt đầu trước khi tất cả các phụ thuộc 'ứng dụng' được bắt đầu, nhưng không thực sự bắt đầu chúng. – nietaki

6

Thành thật mà nói, các công cụ chuẩn để thực hiện việc này trong Erlang là không cần thiết gây phiền nhiễu ngay bây giờ. Tôi có xu hướng đặt lò hơi-tấm sau trong mô-đun callback ứng dụng của tôi:

-module(myapp_app). 
-export([start/0]). 

start() -> a_start(myapp, permanent). 

a_start(App, Type) -> 
    start_ok(App, Type, application:start(App, Type)). 

start_ok(_App, _Type, ok) -> ok; 
start_ok(_App, _Type, {error, {already_started, _App}}) -> ok; 
start_ok(App, Type, {error, {not_started, Dep}}) -> 
    ok = a_start(Dep, Type), 
    a_start(App, Type); 
start_ok(App, _Type, {error, Reason}) -> 
    erlang:error({app_start_failed, App, Reason}). 

Sau đó bạn có thể thêm -s myapp_app vào dòng lệnh erlang bạn và điều này sẽ bắt đầu ứng dụng và tất cả các phụ thuộc của nó một cách đệ quy. Tại sao chức năng này không có trong các mô-đun ứng dụng Tôi không biết :)


Có một ví dụ làm việc của custom erlang app startup code này trong Erlang Factory 2012 SFBay dụ ứng dụng của tôi.