Class: Syntropy::App

Inherits:
Object
  • Object
show all
Defined in:
lib/syntropy/app.rb

Overview

The App implements a Syntropy application. It is responsible for handling incoming HTTP requests, routing them to the correct handler, and maintaining application state.

Constant Summary collapse

BUILTIN_APPLET_app_root =
File.expand_path(File.join(__dir__, 'applets/builtin'))

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(**env) ⇒ void

Initializes the app instance.

Parameters:

  • env (Hash)

    environment hash



76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/syntropy/app.rb', line 76

def initialize(**env)
  @machine = env[:machine]
  @app_root = File.expand_path(env[:app_root])
  @mount_path = env[:mount_path]
  @env = env
  @logger = env[:logger]

  @module_loader = Syntropy::ModuleLoader.new(
    env.merge(app: self),
    extensions: ControllerExtensions
  )
  setup_routing_tree
  start
end

Instance Attribute Details

#app_rootObject (readonly)

Returns the value of attribute app_root.



69
70
71
# File 'lib/syntropy/app.rb', line 69

def app_root
  @app_root
end

#envObject (readonly)

Returns the value of attribute env.



69
70
71
# File 'lib/syntropy/app.rb', line 69

def env
  @env
end

#module_loaderObject (readonly)

Returns the value of attribute module_loader.



69
70
71
# File 'lib/syntropy/app.rb', line 69

def module_loader
  @module_loader
end

#mount_pathObject (readonly)

Returns the value of attribute mount_path.



69
70
71
# File 'lib/syntropy/app.rb', line 69

def mount_path
  @mount_path
end

#raise_on_internal_server_errorObject

Returns the value of attribute raise_on_internal_server_error.



70
71
72
# File 'lib/syntropy/app.rb', line 70

def raise_on_internal_server_error
  @raise_on_internal_server_error
end

#routing_treeObject (readonly)

Returns the value of attribute routing_tree.



69
70
71
# File 'lib/syntropy/app.rb', line 69

def routing_tree
  @routing_tree
end

Class Method Details

.builtin_applet(env, mount_path: '/.syntropy') ⇒ Syntropy::App

Creates a builtin applet with the given environment hash. By default the builtin applet is mounted at /.syntropy.

Parameters:

  • env (Hash)

    app environment

  • mount_path (String) (defaults to: '/.syntropy')

    mount path for the builtin applet

Returns:



36
37
38
39
40
41
42
43
44
# File 'lib/syntropy/app.rb', line 36

def builtin_applet(env, mount_path: '/.syntropy')
  new(
    machine:    env[:machine],
    app_root:   BUILTIN_APPLET_app_root,
    mount_path: mount_path,
    builtin_applet_path: nil,
    watch_files: nil
  )
end

.load(env) ⇒ Syntropy::App

Creates an app instance based on the given environment hash.

Parameters:

  • env (Hash)

    environment hash

Returns:



24
25
26
# File 'lib/syntropy/app.rb', line 24

def load(env)
  site_file_app(env) || default_app(env)
end

Instance Method Details

#call(req) ⇒ void

This method returns an undefined value.

Processes an incoming HTTP request. Requests are processed by first looking up the route for the request path, then calling the route proc. If the route proc is not set, it is computed according to the route target, and composed recursively into hooks encountered up the routing tree.

Normal exceptions (StandardError and descendants) are trapped and passed to route’s error handler. If no such handler is found, the default error handler is used, which simply generates a textual response containing the error message, and with the appropriate HTTP status code, according to the type of error.

Parameters:



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/syntropy/app.rb', line 104

def call(req)
  path = req.path
  route = @router_proc.(path, req.route_params)
  if !route
    if (m = path.match(/^(.+)\/$/))
      return req.redirect(m[1], HTTP::MOVED_PERMANENTLY)
    else
      return handle_not_found(req)
    end
  end

  req.route = route
  proc = route[:proc] ||= compute_route_proc(route)
  proc.(req)
rescue ScriptError, StandardError => e
  if Error.log_error?(e)
    @logger&.error(
      message: "Error while serving request: #{e.message}",
      method: req.method,
      path: path,
      error: e
    )
  end
  error_handler = get_error_handler(route)
  error_handler.(req, e)
end

#route(path, params = {}, compute_proc: false) ⇒ Hash

Returns the route entry for the given path. If compute_proc is true, computes the route proc if not yet computed.

Parameters:

  • path (String)

    path

  • params (Hash) (defaults to: {})

    hash receiving path parameters

  • compute_proc (bool) (defaults to: false)

    whether to compute the route proc

Returns:

  • (Hash)

    route entry



138
139
140
141
142
143
144
# File 'lib/syntropy/app.rb', line 138

def route(path, params = {}, compute_proc: false)
  route = @router_proc.(path, params)
  return if !route

  route[:proc] ||= compute_route_proc(route) if compute_proc
  route
end