Erlang -- Included Applications

OTP Design Principles

User's Guide

Version 10.3

- User's Guide
- PDF
- Top

- Expand All
- Contract All

### Chapters

- Overview
  - Top of chapter
  - Supervision Trees
  - Behaviours
  - Applications
  - Releases
  - Release Handling
- gen_server Behaviour
  - Top of chapter
  - Client-Server Principles
  - Example
  - Starting a Gen_Server
  - Synchronous Requests - Call
  - Asynchronous Requests - Cast
  - Stopping
  - Handling Other Messages
- gen_statem Behavior
  - Top of chapter
  - Event-Driven State Machines
  - When to use gen_statem
  - Callback Module
  - Callback Modes
  - Event Handler
  - State Transition Actions
  - Event Types
  - State Enter Calls
  - Example
  - Starting gen_statem
  - Handling Events
  - State Time-Outs
  - All State Events
  - One Event Handler
  - Stopping
  - Event Time-Outs
  - Generic Time-Outs
  - Erlang Timers
  - Postponing Events
  - State Enter Actions
  - Inserted Events
  - Example Revisited
  - Filter the State
  - Complex State
  - Hibernation
- gen_event Behaviour
  - Top of chapter
  - Event Handling Principles
  - Example
  - Starting an Event Manager
  - Adding an Event Handler
  - Notifying about Events
  - Deleting an Event Handler
  - Stopping
  - Handling Other Messages
- Supervisor Behaviour
  - Top of chapter
  - Supervision Principles
  - Example
  - Supervisor Flags
  - Restart Strategy
  - Maximum Restart Intensity
  - Child Specification
  - Starting a Supervisor
  - Adding a Child Process
  - Stopping a Child Process
  - Simplified one_for_one Supervisors
  - Stopping
- sys and proc_lib
  - Top of chapter
  - Simple Debugging
  - Special Processes
  - User-Defined Behaviours
- Applications
  - Top of chapter
  - Application Concept
  - Application Callback Module
  - Application Resource File
  - Directory Structure
  - Application Controller
  - Loading and Unloading Applications
  - Starting and Stopping Applications
  - Configuring an Application
  - Application Start Types
- Included Applications
  - Top of chapter
  - Introduction
  - Specifying Included Applications
  - Synchronizing Processes during Startup
- Distributed Applications
  - Top of chapter
  - Introduction
  - Specifying Distributed Applications
  - Starting and Stopping Distributed Applications
  - Failover
  - Takeover
- Releases
  - Top of chapter
  - Release Concept
  - Release Resource File
  - Generating Boot Scripts
  - Creating a Release Package
  - Directory Structure
- Release Handling
  - Top of chapter
  - Release Handling Principles
  - Requirements
  - Distributed Systems
  - Release Handling Instructions
  - Application Upgrade File
  - Release Upgrade File
  - Installing a Release
  - Updating Application Specifications
- Appup Cookbook
  - Top of chapter
  - Changing a Functional Module
  - Changing a Residence Module
  - Changing a Callback Module
  - Changing Internal State
  - Module Dependencies
  - Changing Code for a Special Process
  - Changing a Supervisor
  - Adding or Deleting a Module
  - Starting or Terminating a Process
  - Adding or Removing an Application
  - Restarting an Application
  - Changing an Application Specification
  - Changing Application Configuration
  - Changing Included Applications
  - Changing Non-Erlang Code
  - Emulator Restart and Upgrade
  - Emulator Upgrade From Pre OTP R15

# 8 Included Applications

### 8.1 Introduction

An application can include other applications. An included application has its own application directory and .app file, but it is started as part of the supervisor tree of another application.

An application can only be included by one other application.

An included application can include other applications.

An application that is not included by any other application is called a primary application.

Figure 8.1: Primary Application and Included Applications

The application controller automatically loads any included applications when loading a primary application, but does not start them. Instead, the top supervisor of the included application must be started by a supervisor in the including application.

This means that when running, an included application is in fact part of the primary application, and a process in an included application considers itself belonging to the primary application.

### 8.2 Specifying Included Applications

Which applications to include is defined by the included_applications key in the .app file:

    {application, prim_app,
     [{description, "Tree application"},
      {vsn, "1"},
      {modules, [prim_app_cb, prim_app_sup, prim_app_server]},
      {registered, [prim_app_server]},
      {included_applications, [incl_app]},
      {applications, [kernel, stdlib, sasl]},
      {mod, {prim_app_cb,[]}},
      {env, [{file, "/usr/local/log"}]}
     ]}.

### 8.3 Synchronizing Processes during Startup

The supervisor tree of an included application is started as part of the supervisor tree of the including application. If there is a need for synchronization between processes in the including and included applications, this can be achieved by using start phases.

Start phases are defined by the start_phases key in the .app file as a list of tuples {Phase,PhaseArgs}, where Phase is an atom and PhaseArgs is a term.

The value of the mod key of the including application must be set to {application_starter,[Module,StartArgs]}, where Module as usual is the application callback module. StartArgs is a term provided as argument to the callback function Module:start/2:

    {application, prim_app,
     [{description, "Tree application"},
      {vsn, "1"},
      {modules, [prim_app_cb, prim_app_sup, prim_app_server]},
      {registered, [prim_app_server]},
      {included_applications, [incl_app]},
      {start_phases, [{init,[]}, {go,[]}]},
      {applications, [kernel, stdlib, sasl]},
      {mod, {application_starter,[prim_app_cb,[]]}},
      {env, [{file, "/usr/local/log"}]}
     ]}.

    {application, incl_app,
     [{description, "Included application"},
      {vsn, "1"},
      {modules, [incl_app_cb, incl_app_sup, incl_app_server]},
      {registered, []},
      {start_phases, [{go,[]}]},
      {applications, [kernel, stdlib, sasl]},
      {mod, {incl_app_cb,[]}}
     ]}.

When starting a primary application with included applications, the primary application is started the normal way, that is:

- The application controller creates an application master for the application
- The application master calls Module:start(normal, StartArgs) to start the top supervisor.

Then, for the primary application and each included application in top-down, left-to-right order, the application master calls Module:start_phase(Phase, Type, PhaseArgs) for each phase defined for the primary application, in that order. If a phase is not defined for an included application, the function is not called for this phase and application.

The following requirements apply to the .app file for an included application:

- The {mod, {Module,StartArgs}} option must be included. This option is used to find the callback module Module of the application. StartArgs is ignored, as Module:start/2 is called only for the primary application.
- If the included application itself contains included applications, instead the {mod, {application_starter, [Module,StartArgs]}} option must be included.
- The {start_phases, [{Phase,PhaseArgs}]} option must be included, and the set of specified phases must be a subset of the set of phases specified for the primary application.

When starting prim_app as defined above, the application controller calls the following callback functions before application:start(prim_app) returns a value:

    application:start(prim_app)
     => prim_app_cb:start(normal, [])
     => prim_app_cb:start_phase(init, normal, [])
     => prim_app_cb:start_phase(go, normal, [])
     => incl_app_cb:start_phase(go, normal, [])
    ok