aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2013-11-25 15:02:42 +0100
committerLoïc Hoguin <[email protected]>2013-11-25 15:02:42 +0100
commitd2318c0a286daf51b4fe8afc5c6a232eee71ca72 (patch)
tree30a4e2cfa6f6d63c9068145eb82e9ec77c48ec2b
parente4b3cf94ea41963fa0d65559e7ebb271bd96ba55 (diff)
downloadranch-d2318c0a286daf51b4fe8afc5c6a232eee71ca72.tar.gz
ranch-d2318c0a286daf51b4fe8afc5c6a232eee71ca72.tar.bz2
ranch-d2318c0a286daf51b4fe8afc5c6a232eee71ca72.zip
Add a manual
This is the manual for what is going to be in 1.0. It includes two things that are not in the code yet: the shutdown option and the accept_ack transport callback.
-rw-r--r--README.md4
-rw-r--r--manual/ranch.md171
-rw-r--r--manual/ranch_app.md28
-rw-r--r--manual/ranch_protocol.md35
-rw-r--r--manual/ranch_ssl.md97
-rw-r--r--manual/ranch_tcp.md47
-rw-r--r--manual/ranch_transport.md197
-rw-r--r--manual/toc.md11
8 files changed, 588 insertions, 2 deletions
diff --git a/README.md b/README.md
index fafd1cc..570d27d 100644
--- a/README.md
+++ b/README.md
@@ -22,9 +22,9 @@ to close any of the currently opened sockets.
Getting started
---------------
- * [Read the guide](http://ninenines.eu/docs/en/ranch/HEAD/guide/)
+ * [Read the guide](http://ninenines.eu/docs/en/ranch/HEAD/guide)
+ * [Check the manual](http://ninenines.eu/docs/en/ranch/HEAD/manual)
* Look at the examples in the `examples/` directory
- * Build API documentation with `make docs`; open `doc/index.html`
Support
-------
diff --git a/manual/ranch.md b/manual/ranch.md
new file mode 100644
index 0000000..cf4ebe5
--- /dev/null
+++ b/manual/ranch.md
@@ -0,0 +1,171 @@
+ranch
+=====
+
+The `ranch` module provides functions for starting and
+manipulating Ranch listeners.
+
+Types
+-----
+
+### max_conns() = non_neg_integer() | infinity
+
+> Maximum number of connections allowed on this listener.
+>
+> This is a soft limit. The actual number of connections
+> might be slightly above the limit due to concurrency
+> when accepting new connections. Some connections may
+> also be removed from this count explicitly by the user
+> code.
+
+### ref() = any()
+
+> Unique name used to refer to a listener.
+
+Exports
+-------
+
+### accept_ack(Ref) -> ok
+
+> Types:
+> * Ref = ref()
+>
+> Acknowledge that the connection is accepted.
+>
+> This function MUST be used by a connection process to inform
+> Ranch that it initialized properly and let it perform any
+> additional operations before the socket can be safely used.
+
+### child_spec(Ref, NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts)
+ -> supervisor:child_spec()
+
+> Types:
+> * Ref = ref()
+> * NbAcceptors = non_neg_integer()
+> * Transport = module()
+> * TransOpts = any()
+> * Protocol = module()
+> * ProtoOpts = any()
+>
+> Return child specifications for a new listener.
+>
+> This function can be used to embed a listener directly
+> in an application instead of letting Ranch handle it.
+
+### get_max_connections(Ref) -> MaxConns
+
+> Types:
+> * Ref = ref()
+> * MaxConns = max_conns()
+>
+> Return the max number of connections allowed for the given listener.
+
+### get_port(Ref) -> Port
+
+> Types:
+> * Ref = ref()
+> * Port = inet:port_number()
+>
+> Return the port for the given listener.
+
+### get_protocol_options(Ref) -> ProtoOpts
+
+> Types:
+> * Ref = ref()
+> * ProtoOpts = any()
+>
+> Return the protocol options set for the given listener.
+
+### remove_connection(Ref) -> ok
+
+> Types:
+> * Ref = ref()
+>
+> Do not count this connection when limiting the number of connections.
+>
+> You can use this function for long-running connection processes
+> which spend most of their time idling rather than consuming
+> resources. This allows Ranch to accept a lot more connections
+> without sacrificing the latency of the system.
+>
+> This function may only be called from a connection process.
+
+### set_max_connections(Ref, MaxConns) -> ok
+
+> Types:
+> * Ref = ref()
+> * MaxConns = max_conns()
+>
+> Set the max number of connections for the given listener.
+>
+> The change will be applied immediately. If the new value is
+> smaller than the previous one, Ranch will not kill the extra
+> connections, but will wait for them to terminate properly.
+
+### set_protocol_options(Ref, ProtoOpts) -> ok
+
+> Types:
+> * Ref = ref()
+> * ProtoOpts = any()
+>
+> Set the protocol options for the given listener.
+>
+> The change will be applied immediately for all new connections.
+> Old connections will not receive the new options.
+
+### start_listener(Ref, NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts)
+ -> {ok, pid()} | {error, badarg}
+
+> Types:
+> * Ref = ref()
+> * NbAcceptors = non_neg_integer()
+> * Transport = module()
+> * TransOpts = any()
+> * Protocol = module()
+> * ProtoOpts = any()
+>
+> Start listening for connections using the given transport
+> and protocol. Returns the pid for this listener's supervisor.
+>
+> There are five additional transport options that apply
+> regardless of transport. They allow configuring how the
+> connections are supervised, rate limited and allow using
+> an already open listening socket.
+>
+> The `ack_timeout` option defines how long post-accept socket
+> initialization should take at a maximum. It defaults to `5000`.
+>
+> The `connection_type` option defines the type of process
+> that will handle the connection. It can be either `worker`
+> or `supervisor`. It defaults to `worker`.
+>
+> The `max_connections` option determines how many active
+> connections are allowed before Ranch starts throttling
+> the accept rate. This is a soft limit. It defaults to `1024`.
+> Using the value `infinity` will disable this functionality
+> entirely.
+>
+> The `shutdown` option determines the policy used with
+> regards to connection processes when shutting down the listener.
+> It can be either a positive integer indicating the max number
+> of ms the supervisor will wait before forcibly killing the
+> children, or the atom `brutal_kill`. It defaults to `5000`.
+>
+> The `socket` option allow passing an already open listening
+> socket. In this case, Ranch will not call `Transport:listen/1`
+> and so none of the transport specific options apply.
+
+### stop_listener(Ref) -> ok | {error, not_found}
+
+> Types:
+> * Ref = ref()
+>
+> Stop the given listener.
+>
+> The listener is stopped gracefully, first by closing the
+> listening port, then by stopping the connection processes.
+> These processes are stopped according to the `shutdown`
+> transport option, which may be set to brutally kill all
+> connection processes or give them some time to stop properly.
+>
+> This function does not return until the listener is
+> completely stopped.
diff --git a/manual/ranch_app.md b/manual/ranch_app.md
new file mode 100644
index 0000000..380931c
--- /dev/null
+++ b/manual/ranch_app.md
@@ -0,0 +1,28 @@
+The Ranch Application
+=====================
+
+Socket acceptor pool for TCP protocols.
+
+Dependencies
+------------
+
+The `ranch` application has no particular dependency required
+to start.
+
+It has optional dependencies that are only required when
+listening for SSL connections. The dependencies are `crypto`,
+`asn1`, `public_key` and `ssl`. They are started automatically
+if they weren't before.
+
+Environment
+-----------
+
+The `ranch` application defines one application environment
+configuration parameter.
+
+ - profile (false)
+ - When enabled, Ranch will start `etop` profiling automatically.
+
+You can use the `ranch_app:profile_output/0` function to stop
+profiling and output the results to the files `procs.profile`
+and `total.profile`. Do not use in production.
diff --git a/manual/ranch_protocol.md b/manual/ranch_protocol.md
new file mode 100644
index 0000000..3e8b62e
--- /dev/null
+++ b/manual/ranch_protocol.md
@@ -0,0 +1,35 @@
+ranch_protocol
+==============
+
+The `ranch_protocol` behaviour defines the interface used
+by Ranch protocols.
+
+Types
+-----
+
+None.
+
+Callbacks
+---------
+
+### start_link(Ref, Socket, Transport, ProtoOpts) -> {ok, pid()}
+
+> Types:
+> * Ref = ranch:ref()
+> * Socket = any()
+> * Transport = module()
+> * ProtoOpts = any()
+>
+> Start a new connection process for the given socket.
+>
+> The only purpose of this callback is to start a process that
+> will handle the socket. It must spawn the process, link and
+> then return the new pid. This function will always be called
+> from inside a supervisor.
+>
+> If any other value is returned, the supervisor will close the
+> socket and assume no process has been started.
+>
+> Do not perform any operation in this callback, as this would
+> block the supervisor responsible for starting connection
+> processes and degrade performance severely.
diff --git a/manual/ranch_ssl.md b/manual/ranch_ssl.md
new file mode 100644
index 0000000..d8bb140
--- /dev/null
+++ b/manual/ranch_ssl.md
@@ -0,0 +1,97 @@
+ranch_ssl
+=========
+
+The `ranch_ssl` module implements an SSL Ranch transport.
+
+Types
+-----
+
+### opts() = [{backlog, non_neg_integer()}
+ | {cacertfile, string()}
+ | {cacerts, [Der::binary()]}
+ | {cert, Der::binary()}
+ | {certfile, string()}
+ | {ciphers, [ssl:erl_cipher_suite()] | string()}
+ | {fail_if_no_peer_cert, boolean()}
+ | {hibernate_after, integer() | undefined}
+ | {ip, inet:ip_address()}
+ | {key, Der::binary()}
+ | {keyfile, string()}
+ | {next_protocols_advertised, [binary()]}
+ | {nodelay, boolean()}
+ | {password, string()}
+ | {port, inet:port_number()}
+ | {raw, non_neg_integer(), non_neg_integer(), non_neg_integer() | binary()}
+ | {reuse_session, fun()}
+ | {reuse_sessions, boolean()}
+ | {secure_renegotiate, boolean()}
+ | {verify, ssl:verify_type()}
+ | {verify_fun, {fun(), InitialUserState::term()}}]
+
+> Listen options.
+>
+> This does not represent the entirety of the options that can
+> be set on the socket, but only the options that should be
+> set independently of protocol implementation.
+
+Option descriptions
+-------------------
+
+Specifying a certificate is mandatory, either through the `cert`
+or the `certfile` option. None of the other options are required.
+
+The default value is given next to the option name.
+
+ - backlog (1024)
+ - Max length of the queue of pending connections.
+ - cacertfile
+ - Path to PEM encoded trusted certificates file used to verify peer certificates.
+ - cacerts
+ - List of DER encoded trusted certificates.
+ - cert
+ - DER encoded user certificate.
+ - certfile
+ - Path to the PEM encoded user certificate file. May also contain the private key.
+ - ciphers
+ - List of ciphers that clients are allowed to use.
+ - fail_if_no_peer_cert (false)
+ - Whether to refuse the connection if the client sends an empty certificate.
+ - hibernate_after (undefined)
+ - Time in ms after which SSL socket processes go into hibernation to reduce memory usage.
+ - ip
+ - Interface to listen on. Listen on all interfaces by default.
+ - key
+ - DER encoded user private key.
+ - keyfile
+ - Path to the PEM encoded private key file, if different than the certfile.
+ - next_protocols_advertised
+ - List of protocols to send to the client if it supports the Next Protocol extension.
+ - nodelay (true)
+ - Whether to enable TCP_NODELAY.
+ - password
+ - Password to the private key file, if password protected.
+ - port (0)
+ - TCP port number to listen on. 0 means a random port will be used.
+ - reuse_session
+ - Custom policy to decide whether a session should be reused.
+ - reuse_sessions (false)
+ - Whether to allow session reuse.
+ - secure_renegotiate (false)
+ - Whether to reject renegotiation attempts that do not conform to RFC5746.
+ - verify (verify_none)
+ - Use `verify_peer` to request a certificate from the client.
+ - verify_fun
+ - Custom policy to decide whether a client certificate is valid.
+
+Note that the client will not send a certificate unless the
+value for the `verify` option is set to `verify_peer`. This
+means that the `fail_if_no_peer_cert` only apply when combined
+with the `verify` option. The `verify_fun` option allows
+greater control over the client certificate validation.
+
+The `raw` option is unsupported.
+
+Exports
+-------
+
+None.
diff --git a/manual/ranch_tcp.md b/manual/ranch_tcp.md
new file mode 100644
index 0000000..d0f6054
--- /dev/null
+++ b/manual/ranch_tcp.md
@@ -0,0 +1,47 @@
+ranch_tcp
+=========
+
+The `ranch_tcp` module implements a TCP Ranch transport.
+
+Note that due to bugs in OTP up to at least R16B02, it is
+recommended to disable async threads when using the
+`sendfile` function of this transport, as it can make
+the threads stuck indefinitely.
+
+Types
+-----
+
+### opts() = [{backlog, non_neg_integer()}
+ | {ip, inet:ip_address()}
+ | {nodelay, boolean()}
+ | {port, inet:port_number()}
+ | {raw, non_neg_integer(), non_neg_integer(), non_neg_integer() | binary()}]
+
+> Listen options.
+>
+> This does not represent the entirety of the options that can
+> be set on the socket, but only the options that should be
+> set independently of protocol implementation.
+
+Option descriptions
+-------------------
+
+None of the options are required.
+
+The default value is given next to the option name.
+
+ - backlog (1024)
+ - Max length of the queue of pending connections.
+ - ip
+ - Interface to listen on. Listen on all interfaces by default.
+ - nodelay (true)
+ - Whether to enable TCP_NODELAY.
+ - port (0)
+ - TCP port number to listen on. 0 means a random port will be used.
+
+The `raw` option is unsupported.
+
+Exports
+-------
+
+None.
diff --git a/manual/ranch_transport.md b/manual/ranch_transport.md
new file mode 100644
index 0000000..7eb350d
--- /dev/null
+++ b/manual/ranch_transport.md
@@ -0,0 +1,197 @@
+ranch_transport
+===============
+
+The `ranch_transport` behaviour defines the interface used
+by Ranch transports.
+
+Types
+-----
+
+### sendfile_opts() = [{chunk_size, non_neg_integer()}]
+
+> Options used by the sendfile function and callbacks.
+>
+> Allows configuring the chunk size, in bytes. Defaults to 8191 bytes.
+
+Callbacks
+---------
+
+### accept(LSocket, Timeout)
+ -> {ok, CSocket} | {error, closed | timeout | atom() | tuple()}
+
+> Types:
+> * LSocket = CSocket = any()
+> * Timeout = timeout()
+>
+> Accept a connection on the given listening socket.
+>
+> The `accept_ack` callback will be used to initialize the socket
+> after accepting the connection. This is most useful when the
+> transport is not raw TCP, like with SSL for example.
+
+### accept_ack(CSocket, Timeout) -> ok
+
+> Types:
+> * CSocket = any()
+> * Timeout = timeout()
+>
+> Perform post-accept initialization of the connection.
+>
+> This function will be called by connection processes
+> before performing any socket operation. It allows
+> transports that require extra initialization to perform
+> their task and make the socket ready to use.
+
+### close(CSocket) -> ok
+
+> Types:
+> * CSocket = any()
+>
+> Close the given socket.
+
+### controlling_process(CSocket, Pid)
+ -> ok | {error, closed | not_owner | atom()}
+
+> Types:
+> * CSocket = any()
+> * Pid = pid()
+>
+> Change the controlling process for the given socket.
+>
+> The controlling process is the process that is allowed to
+> perform operations on the socket, and that will receive
+> messages from the socket when active mode is used. When
+> the controlling process dies, the socket is closed.
+
+### listen(TransOpts) -> {ok, LSocket} | {error, atom()}
+
+> Types:
+> * TransOpts = any()
+> * LSocket = any()
+>
+> Listen for connections on the given port.
+>
+> The port is given as part of the transport options under
+> the key `port`. Any other option is transport dependent.
+>
+> The socket returned by this call can then be used to
+> accept connections. It is not possible to send or receive
+> data from the listening socket.
+
+### messages() -> {OK, Closed, Error}
+
+> Types:
+> * OK = Closed = Error = atom()
+>
+> Return the atoms used to identify messages sent in active mode.
+
+### name() -> Name
+
+> Types:
+> * Name = atom()
+>
+> Return the name of the transport.
+
+### peername(CSocket) -> {ok, {IP, Port}} | {error, atom()}
+
+> Types:
+> * CSocket = any()
+> * IP = inet:ip_address()
+> * Port = inet:port_number()
+>
+> Return the IP and port of the remote endpoint.
+
+### recv(CSocket, Length, Timeout)
+ -> {ok, Packet} | {error, closed | timeout | atom()}
+
+> Types:
+> * CSocket = any()
+> * Length = non_neg_integer()
+> * Timeout = timeout()
+> * Packet = iodata() | any()
+>
+> Receive data from the given socket when in passive mode.
+>
+> Trying to receive data from a socket that is in active mode
+> will return an error.
+>
+> A length of 0 will return any data available on the socket.
+>
+> While it is possible to use the timeout value `infinity`,
+> this is highly discouraged as this could cause your process
+> to get stuck waiting for data that will never come. This may
+> happen when a socket becomes half-open due to a crash of the
+> remote endpoint. Wi-Fi going down is another common culprit
+> of this issue.
+
+### send(CSocket, Packet) -> ok | {error, atom()}
+
+> Types:
+> * CSocket = any()
+> * Packet = iodata()
+>
+> Send data to the given socket.
+
+### sendfile(CSocket, File)
+ -> sendfile(CSocket, File, 0, 0, [])
+### sendfile(CSocket, File, Offset, Bytes)
+ -> sendfile(CSocket, File, Offset, Bytes, [])
+### sendfile(CSocket, File, Offset, Bytes, SfOpts)
+ -> {ok, SentBytes} | {error, atom()}
+
+> Types:
+> * CSocket = any()
+> * File = file:filename_all() | file:fd()
+> * Offset = non_neg_integer()
+> * Bytes = SentBytes = non_neg_integer()
+> * SfOpts = sendfile_opts()
+>
+> Send data from a file to the given socket.
+>
+> The file may be sent full or in parts, and may be specified
+> by its filename or by an already open file descriptor.
+>
+> Transports that manipulate TCP directly may use the
+> `file:sendfile/{2,4,5}` function, which calls the sendfile
+> syscall where applicable (on Linux, for example). Other
+> transports can use the `sendfile/6` function exported from
+> this module.
+
+### setopts(CSocket, TransOpts) -> ok | {error, atom()}
+
+> Types:
+> * CSocket = any()
+> * TransOpts = any()
+>
+> Change transport options for the given socket.
+>
+> This is mainly useful for switching to active or passive mode.
+
+### sockname(CSocket) -> {ok, {IP, Port}} | {error, atom()}
+
+> Types:
+> * CSocket = any()
+> * IP = inet:ip_address()
+> * Port = inet:port_number()
+>
+> Return the IP and port of the local endpoint.
+
+Exports
+-------
+
+### sendfile(Transport, CSocket, File, Offset, Bytes, SfOpts)
+ -> {ok, SentBytes} | {error, atom()}
+
+> Types:
+> * Transport = module()
+> * CSocket = any()
+> * File = file:filename_all() | file:fd()
+> * Offset = non_neg_integer()
+> * Bytes = SentBytes = non_neg_integer()
+> * SfOpts = sendfile_opts()
+>
+> Send data from a file to the given socket.
+>
+> This function emulates the function `file:sendfile/{2,4,5}`
+> and may be used when transports are not manipulating TCP
+> directly.
diff --git a/manual/toc.md b/manual/toc.md
new file mode 100644
index 0000000..af99d14
--- /dev/null
+++ b/manual/toc.md
@@ -0,0 +1,11 @@
+Ranch Function Reference
+========================
+
+The function reference documents the public interface of Ranch.
+
+ * [The Ranch Application](ranch_app.md)
+ * [ranch](ranch.md)
+ * [ranch_protocol](ranch_protocol.md)
+ * [ranch_ssl](ranch_ssl.md)
+ * [ranch_tcp](ranch_tcp.md)
+ * [ranch_transport](ranch_transport.md)