+
Skip to content

karlsson/glite

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

glite

The Gleamlins little intro to Erlang applications

The Erlang documentation for applications states:

After creating code to implement a specific functionality, you might consider transforming it into an application — a component that can be started and stopped as a unit, as well as reused in other systems. 1

So how does one turn a Gleam project into an Erlang application? Well many things are already in place actually. The gleam buildcommand already creates a <project>.appfile in the in the build ebin directory, and that is what the Erlang application controller basically needs.

An Erlang application may come in two "flavours", one as a plain library like stdlib which does not need to start any processes, and one where the application controller starts a service with several processes under a supervision tree. For the second case the controller checks the <project>.app file for the mod property which may look like:

{mod, {'glite_app', []}}

where the second tuple contains the start module and any start arguments.

Configuration

When gleam run is executed it actually starts all registered applications (those having the mod property set). In order to enable it in our application we need to append to the gleam.toml file 2:

[erlang]
application_start_module = "glite_app"

This will add the mod property to the gleam.app file.

Callback functions

In the start module the application controller expects two callback functions to be implemented. Since Gleam compiles to Erlang source there is no problem to implement those in the Gleam project module, glite in this case if you do not prefer a pure erlang callback module:

pub type ErlangResult {
  Ok
}

// --------------------- Erlang/OTP Application part --------------------
/// The Erlang/OTP application start callback.
/// Responsible to start the "top" supervisor process and return its Pid
/// to the application controller.
pub fn start(_app: atom.Atom, _type) -> Result(process.Pid, dynamic.Dynamic) {
  io.println("Application start - starts the top supervisor")
  let assert gleam.Ok(actor.Started(pid, _data)) = start_supervisor()
  gleam.Ok(pid)
}

/// The Erlang/OTP application stop callback.
/// This is called after all processes in the supervisor tree have
/// been shutdown by the application controller. Responsible for any
/// final clean up actions.
pub fn stop(_state: a) -> ErlangResult {
  Ok
}

In our example project we implement the callbacks with some extra optional ones in the erlang module glite_app which in turn calls the glite.start_link function.

Joining the ecosystem

The benefits of doing all this is not obvious, but joining as a complete Erlang application gives the possibility to use diagnostic tools like observerto introspect your processes and trace messages.

pub fn main() {
  io.println("Hello from gliteapp!")
  observer_start()
  process.sleep_forever()
}

type ErlangResult

@external(erlang, "observer", "start")
fn observer_start() -> ErlangResult

This will bring up the observer GUI. You can also use the sys functions from the Erlang shell.

$ gleam shell

  Compiled in 0.07s
   Running Erlang shell
Erlang/OTP 28 [erts-16.0] [source] [64-bit] [smp:8:4] [ds:8:4:10] [async-threads:1] [jit:ns]

Eshell V16.0 (press Ctrl+G to abort, type help(). for help)
1> application:ensure_all_started(glite).
Application start - starts the top supervisor
{ok,[gleam_stdlib,gleam_erlang,gleam_otp,gleeunit,glite]}


7> i().
Pid                   Initial Call                          Heap     Reds Msgs
Registered            Current Function                     Stack              
..
<0.87.0>              application_master:init/3              233      260    0
                      application_master:main_loop/2           6              
<0.88.0>              application_master:start_it/4          233      594    0
                      application_master:loop_it/4             6              
<0.89.0>              supervisor:gleam@otp@static_super       73      301    0
                      gen_server:loop_hibernate/4              8              
..

8> sys:get_state(<0.89.0>).
{state,{<0.89.0>,gleam@otp@static_supervisor},
       rest_for_one,
       {[],#{}},
       undefined,2,5,[],0,0,never,1000,
       #Ref<0.4240582723.2716598273.224777>,
       gleam@otp@static_supervisor,
       {#{intensity => 2,period => 5,strategy => rest_for_one,
          auto_shutdown => never},
        []}}
9> 

gleam run   # Run the project

References

[1]: Applications - Erlang documentation.
[2]: gleam.toml

About

The Gleamlins little intro to Erlang applications

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载