diff options
Diffstat (limited to 'lib/kernel/doc/src')
-rw-r--r-- | lib/kernel/doc/src/Makefile | 110 | ||||
-rw-r--r-- | lib/kernel/doc/src/code.xml | 49 | ||||
-rw-r--r-- | lib/kernel/doc/src/disk_log.xml | 14 | ||||
-rw-r--r-- | lib/kernel/doc/src/erpc.xml | 513 | ||||
-rw-r--r-- | lib/kernel/doc/src/file.xml | 28 | ||||
-rw-r--r-- | lib/kernel/doc/src/gen_sctp.xml | 6 | ||||
-rw-r--r-- | lib/kernel/doc/src/gen_udp.xml | 1 | ||||
-rw-r--r-- | lib/kernel/doc/src/kernel_app.xml | 10 | ||||
-rw-r--r-- | lib/kernel/doc/src/net.xml | 2 | ||||
-rw-r--r-- | lib/kernel/doc/src/pg.xml | 195 | ||||
-rw-r--r-- | lib/kernel/doc/src/pg2.xml | 10 | ||||
-rw-r--r-- | lib/kernel/doc/src/ref_man.xml | 2 | ||||
-rw-r--r-- | lib/kernel/doc/src/rpc.xml | 153 | ||||
-rw-r--r-- | lib/kernel/doc/src/seq_trace.xml | 139 | ||||
-rw-r--r-- | lib/kernel/doc/src/specs.xml | 2 |
15 files changed, 1039 insertions, 195 deletions
diff --git a/lib/kernel/doc/src/Makefile b/lib/kernel/doc/src/Makefile index fe3dc9dab5..9b004b3781 100644 --- a/lib/kernel/doc/src/Makefile +++ b/lib/kernel/doc/src/Makefile @@ -28,11 +28,6 @@ VSN=$(KERNEL_VSN) APPLICATION=kernel # ---------------------------------------------------- -# Release directory specification -# ---------------------------------------------------- -RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN) - -# ---------------------------------------------------- # Target Specs # ---------------------------------------------------- XML_APPLICATION_FILES = ref_man.xml @@ -46,6 +41,7 @@ XML_REF3_FILES = application.xml \ erl_epmd.xml \ erl_prim_loader_stub.xml \ erlang_stub.xml \ + erpc.xml \ error_handler.xml \ error_logger.xml \ file.xml \ @@ -67,6 +63,7 @@ XML_REF3_FILES = application.xml \ net_adm.xml \ net_kernel.xml \ os.xml \ + pg.xml \ pg2.xml \ rpc.xml \ seq_trace.xml \ @@ -96,86 +93,8 @@ XML_FILES = \ $(XML_PART_FILES) $(XML_REF3_FILES) $(XML_REF4_FILES)\ $(XML_REF6_FILES) $(XML_APPLICATION_FILES) -# ---------------------------------------------------- - -HTML_FILES = $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html) \ - $(XML_PART_FILES:%.xml=$(HTMLDIR)/%.html) - -INFO_FILE = ../../info - -MAN3_FILES = $(XML_REF3_FILES:%.xml=$(MAN3DIR)/%.3) -MAN4_FILES = $(XML_REF4_FILES:%.xml=$(MAN4DIR)/%.4) -MAN6_FILES = $(XML_REF6_FILES:%_app.xml=$(MAN6DIR)/%.6) - -HTML_REF_MAN_FILE = $(HTMLDIR)/index.html - -TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf - -SPECS_FILES = $(XML_REF3_FILES:%.xml=$(SPECDIR)/specs_%.xml) - TOP_SPECS_FILE = specs.xml - -# ---------------------------------------------------- -# FIGURES -# ---------------------------------------------------- -# In order to update the figures you have to have both dia -# and imagemagick installed. -# The generated .png file must be committed. - -update_png: - dia --export=logger_arch.eps logger_arch.dia - convert logger_arch.eps -resize 65% logger_arch.png - -# ---------------------------------------------------- -# FLAGS -# ---------------------------------------------------- -XML_FLAGS += - -SPECS_ESRC = ../../src - -SPECS_FLAGS = -I../../include - -# ---------------------------------------------------- -# Targets -# ---------------------------------------------------- -$(HTMLDIR)/%: % - $(INSTALL_DATA) $< $@ - -docs: man pdf html - -$(TOP_PDF_FILE): $(XML_FILES) - -pdf: $(TOP_PDF_FILE) - -html: images $(HTML_REF_MAN_FILE) - -man: $(MAN3_FILES) $(MAN4_FILES) $(MAN6_FILES) - -images: $(IMAGE_FILES:%=$(HTMLDIR)/%) - -info: - @echo "XML_APPLICATION_FILES: $(XML_APPLICATION_FILES)" - @echo "XML_REF3_ESOCK_FILES: $(XML_REF3_ESOCK_FILES)" - @echo "XML_REF3_FILES: $(XML_REF3_FILES)" - @echo "XML_REF4_FILES: $(XML_REF4_FILES)" - @echo "XML_REF6_FILES: $(XML_REF6_FILES)" - @echo "XML_PART_FILES: $(XML_PART_FILES)" - @echo "XML_CHAPTER_FILES: $(XML_CHAPTER_FILES)" - @echo "BOOK_FILES: $(BOOK_FILES)" - -debug opt: - -clean clean_docs: - rm -rf $(HTMLDIR)/* - rm -rf $(XMLDIR) - rm -f $(MAN3DIR)/* - rm -f $(MAN4DIR)/* - rm -f $(MAN6DIR)/* - rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) - rm -f $(SPECDIR)/* - rm -f errs core *~ *.eps - $(SPECDIR)/specs_erl_prim_loader_stub.xml: $(gen_verbose)escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ -o$(dir $@) -module erl_prim_loader_stub @@ -189,24 +108,17 @@ $(SPECDIR)/specs_zlib_stub.xml: $(gen_verbose)escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ -o$(dir $@) -module zlib_stub +NO_CHUNKS = erl_prim_loader_stub.xml erlang_stub.xml init_stub.xml zlib_stub.xml # ---------------------------------------------------- -# Release Target +# FIGURES # ---------------------------------------------------- -include $(ERL_TOP)/make/otp_release_targets.mk +# In order to update the figures you have to have both dia +# and imagemagick installed. +# The generated .png file must be committed. -release_docs_spec: docs - $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" - $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" - $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" - $(INSTALL_DATA) $(HTMLDIR)/* \ - "$(RELSYSDIR)/doc/html" - $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" - $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" - $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" - $(INSTALL_DIR) "$(RELEASE_PATH)/man/man4" - $(INSTALL_DATA) $(MAN4_FILES) "$(RELEASE_PATH)/man/man4" - $(INSTALL_DIR) "$(RELEASE_PATH)/man/man6" - $(INSTALL_DATA) $(MAN6_FILES) "$(RELEASE_PATH)/man/man6" +update_png: + dia --export=logger_arch.eps logger_arch.dia + convert logger_arch.eps -resize 65% logger_arch.png -release_spec: +include $(ERL_TOP)/make/doc.mk diff --git a/lib/kernel/doc/src/code.xml b/lib/kernel/doc/src/code.xml index 4aa9e8b9d2..45538d3239 100644 --- a/lib/kernel/doc/src/code.xml +++ b/lib/kernel/doc/src/code.xml @@ -315,6 +315,9 @@ zip:create("mnesia-4.4.7.ez", <name name="load_error_rsn"/> </datatype> <datatype> + <name name="module_status"/> + </datatype> + <datatype> <name name="prepared_code"/> <desc><p>An opaque term holding prepared code.</p></desc> </datatype> @@ -702,6 +705,21 @@ ok = code:finish_loading(Prepared), </desc> </func> <func> + <name name="all_available" arity="0" since="OTP @OTP-16494@"/> + <fsummary>Get all available modules.</fsummary> + <type name="loaded_filename"/> + <type name="loaded_ret_atoms"/> + <type_desc name="loaded_filename"><c><anno>Filename</anno></c> is an absolute + filename.</type_desc> + <desc> + <p>Returns a list of tuples <c>{<anno>Module</anno>, <anno>Filename</anno>, + <anno>Loaded</anno>}</c> for all available modules. A module is considered + to be available if it either is loaded or would be loaded if called. + <c><anno>Filename</anno></c> is normally the absolute filename, as described for + <seealso marker="#is_loaded/1"><c>is_loaded/1</c></seealso>.</p> + </desc> + </func> + <func> <name name="all_loaded" arity="0" since=""/> <fsummary>Get all loaded modules.</fsummary> <type name="loaded_filename"/> @@ -718,6 +736,7 @@ ok = code:finish_loading(Prepared), <func> <name name="which" arity="1" since=""/> <fsummary>The object code file of a module.</fsummary> + <type name="loaded_filename"/> <type name="loaded_ret_atoms"/> <desc> <p>If the module is not loaded, this function searches the code @@ -750,6 +769,22 @@ rpc:call(Node, code, load_binary, [Module, Filename, Binary]), </desc> </func> <func> + <name name="get_doc" arity="1" since="OTP @OTP-16406@"/> + <fsummary>Gets the documentation for a module.</fsummary> + <desc> + <p>Searches the code path for a documentation chunk + and returns ut if available. If no documentation chunk + can be found the function tries to generate documentation + from the debug information in the module. If no debug + information is available, this function will return + <c>{error,missing}</c>. + </p> + <p>For more information about the documentation chunk see + <seealso marker="erl_docgen:doc_storage">Documentation Storage</seealso> + in Erl_Docgen's User's Guide.</p> + </desc> + </func> + <func> <name name="root_dir" arity="0" since=""/> <fsummary>Root directory of Erlang/OTP.</fsummary> <desc> @@ -901,10 +936,20 @@ rpc:call(Node, code, load_binary, [Module, Filename, Binary]), </desc> </func> <func> + <name name="module_status" arity="0" since="OTP 23.0"/> + <fsummary>Return the statuses of all loaded modules.</fsummary> + <type name="module_status"/> + <desc> + <p>See <seealso marker="#module_status/1"><c>module_status/1</c></seealso> and <seealso marker="#all_loaded/0"><c>all_loaded/0</c></seealso> for details.</p> + </desc> + </func> + <func> <name name="module_status" arity="1" since="OTP 20.0"/> - <fsummary>Return the status of the module in relation to object file on disk.</fsummary> + <fsummary>Return the status of a module or modules in relation to the + object files on disk.</fsummary> + <type name="module_status"/> <desc> - <p>Returns:</p> + <p>The status of a module can be one of:</p> <taglist> <tag><c>not_loaded</c></tag> <item><p>If <c><anno>Module</anno></c> is not currently loaded.</p></item> diff --git a/lib/kernel/doc/src/disk_log.xml b/lib/kernel/doc/src/disk_log.xml index e308b06f3c..4bfe9cb0db 100644 --- a/lib/kernel/doc/src/disk_log.xml +++ b/lib/kernel/doc/src/disk_log.xml @@ -127,6 +127,10 @@ functions fail. The corresponding terms (not the binaries) are returned when <c>chunk/2,3</c> is called. </p> + <note><p> + The distributed disk log feature has been deprecated. This + feature has also been scheduled for removal in OTP 24. + </p></note> <p>A collection of open disk logs with the same name running on different nodes is said to be a <em>distributed disk log</em> if requests made to any of the logs are automatically made to @@ -609,6 +613,10 @@ the current node, <c><anno>Dist</anno></c> has the value <c>local</c>, otherwise all nodes where the log is distributed are returned as a list.</p> + <warning><p> + The distributed disk log feature has been deprecated. This + feature has also been scheduled for removal in OTP 24. + </p></warning> </item> </taglist> <p>The following pairs are returned for all logs opened in @@ -871,7 +879,11 @@ adding members to a distributed disk log. Defaults to <c>[]</c>, which means that the log is local on the current node. - </p> + </p> + <warning><p> + The distributed disk log feature has been deprecated. This + feature has also been scheduled for removal in OTP 24. + </p></warning> </item> <tag><c>{notify, boolean()}</c><marker id="notify"></marker></tag> <item> diff --git a/lib/kernel/doc/src/erpc.xml b/lib/kernel/doc/src/erpc.xml new file mode 100644 index 0000000000..43e25b016b --- /dev/null +++ b/lib/kernel/doc/src/erpc.xml @@ -0,0 +1,513 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2020</year><year>2020</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + </legalnotice> + + <title>erpc</title> + <prepared>Rickard Green</prepared> + <docno>1</docno> + <date>2020-02-20</date> + <rev>A</rev> + </header> + <module since="OTP @OTP-13450@">erpc</module> + <modulesummary>Enhanced Remote Procedure Call</modulesummary> + <description> + <p> + This module provide services similar to Remote Procedure Calls. + A remote procedure call is a method to call a function on a remote + node and collect the answer. It is used for collecting information + on a remote node, or for running a function with some specific side + effects on the remote node. + </p> + <p> + This is an enhanced subset of the operations provided by the + <seealso marker="rpc"><c>rpc</c></seealso> module. Enhanced in the + sense that it makes it possible to distinguish between returned + value, raised exceptions, and other errors. <c>erpc</c> also has + better performance and scalability than the original <c>rpc</c> + implementation. However, current <c>rpc</c> module will utilize + <c>erpc</c> in order to also provide these properties when + possible. + </p> + <p> + In order for an <c>erpc</c> operation to succeed, the remote + node also needs to support <c>erpc</c>. Typically only ordinary + Erlang nodes as of OTP 23 have <c>erpc</c> support. + </p> + </description> + + <datatypes> + <datatype> + <name name="request_id"/> + <desc> + <p> + An opaque type of call request identifiers. For more + information see + <seealso marker="#send_request/4"><c>send_request/4</c></seealso>. + </p> + </desc> + </datatype> + </datatypes> + + <funcs> + + <func> + <name name="call" arity="4" since="OTP @OTP-13450@"/> + <name name="call" arity="5" since="OTP @OTP-13450@"/> + <fsummary>Evaluate a function call on a node.</fsummary> + <desc> + <p> + Evaluates <c>apply(<anno>Module</anno>, <anno>Function</anno>, + <anno>Args</anno>)</c> on node <c><anno>Node</anno></c> and returns + the corresponding value <c><anno>Result</anno></c>. + <c><anno>Timeout</anno></c> is an integer representing + the timeout in milliseconds or the atom <c>infinity</c>. + </p> + <p>The call <c>erpc:call(<anno>Node</anno>, <anno>Module</anno>, + <anno>Function</anno>, <anno>Args</anno>)</c> is equivalent + to the call <c>erpc:call(<anno>Node</anno>, <anno>Module</anno>, + <anno>Function</anno>, <anno>Args</anno>, infinity)</c></p> + <p> + The <c>call()</c> function only returns if the applied + function successfully returned without raising any uncaught + exceptions, the operation did not time out, and no failures + occurred. In all other cases an exception is raised. The + following exceptions, listed by exception class, can + currently be raised by <c>erpc:call()</c>: + </p> + <taglist> + <tag><c>throw</c></tag> + <item><p> + The applied function called <c>throw(Value)</c> + and did not catch this exception. The exception + reason <c>Value</c> equals the argument passed to + <c>throw/1</c>. + </p></item> + + <tag><c>exit</c></tag> + <item><p> + Exception reason: + </p> + <taglist> + <tag><c>{exception, ExitReason}</c></tag> + <item><p> + The applied function called <c>exit(ExitReason)</c> + and did not catch this exception. The exit + reason <c>ExitReason</c> equals the argument passed + to <c>exit/1</c>. + </p></item> + <tag><c>{signal, ExitReason}</c></tag> + <item><p> + The process that applied the function received an + exit signal and terminated due to this signal. The + process terminated with exit reason <c>ExitReason</c>. + </p></item> + </taglist> + </item> + + <tag><c>error</c></tag> + <item><p> + Exception reason: + </p> + <taglist> + + <tag><c>{exception, ErrorReason, StackTrace}</c></tag> + <item><p> + A runtime error occurred which raised and error + exception while applying the function, + and the applied function did not catch the + exception. The error reason <c>ErrorReason</c> + indicates the type of error that occurred. + <c>StackTrace</c> is formatted as when caught in a + <c>try/catch</c> construct. The <c>StackTrace</c> + is limited to the applied function and functions + called by it. + </p></item> + + <tag><c>{erpc, ERpcErrorReason}</c></tag> + <item><p> + The <c>erpc</c> operation failed. The following + <c>ERpcErrorReason</c>s are the most common ones: + </p> + + <taglist> + <tag><c>badarg</c></tag> + <item> + <p>If any one of these are true:</p> + <list> + <item><p><c><anno>Node</anno></c> is not a valid + node name atom.</p></item> + <item><p><c><anno>Module</anno></c> is not an atom.</p></item> + <item><p><c><anno>Function</anno></c> is not an atom.</p></item> + <item><p><c><anno>Args</anno></c> is not a proper list + of terms.</p></item> + <item><p><c><anno>Timeout</anno></c> is not the + atom <c>infinity</c> or an integer in valid + range.</p></item> + </list> + </item> + + <tag><c>noconnection</c></tag> + <item><p> + The connection to <c>Node</c> was lost or could + not be established. The function may or may not + be applied. + </p></item> + + <tag><c>system_limit</c></tag> + <item><p> + The <c>erpc</c> operation failed due to some system + limit being reached. This typically due to failure + to create a process on the remote node <c>Node</c>, + but can be other things as well. + </p></item> + + <tag><c>timeout</c></tag> + <item><p> + The <c>erpc</c> operation timed out. The function may + or may not be applied. + </p></item> + + <tag><c>notsup</c></tag> + <item><p> + The remote node <c>Node</c> does not support + this <c>erpc</c> operation. + </p> + </item> + + </taglist> + </item> + + </taglist> + </item> + </taglist> + + <p> + If the <c>erpc</c> operation fails, but it is unknown if + the function is/will be applied (that is, a timeout or + a connection loss), the caller will not receive any + further information about the result if/when the applied + function completes. If the applied function explicitly + communicates with the calling process, such communication + may, of course, reach the calling process. + </p> + + <note> + <p> + You cannot make <em>any</em> assumptions about the + process that will perform the <c>apply()</c>. It may + be the calling process itself, a server, or a freshly + spawned process. + </p> + </note> + </desc> + </func> + + <func> + <name name="cast" arity="4" since="OTP @OTP-13450@"/> + <fsummary>Evaluate a function call on a node ignoring the result.</fsummary> + <desc> + <p> + Evaluates <c>apply(<anno>Module</anno>, <anno>Function</anno>, + <anno>Args</anno>)</c> on node + <c><anno>Node</anno></c>. No response is delivered to the + calling process. <c>erpc:cast()</c> returns immediately + after the cast request has been sent. Any failures beside + bad arguments are silently ignored. + </p> + <p><c>erpc:cast/4</c> fails with an <c>{erpc, badarg}</c> + <c>error</c> exception if:</p> + <list> + <item><p><c><anno>Node</anno></c> is not a valid + node name atom.</p></item> + <item><p><c><anno>Module</anno></c> is not an atom.</p></item> + <item><p><c><anno>Function</anno></c> is not an atom.</p></item> + <item><p><c><anno>Args</anno></c> is not a proper list + of terms.</p></item> + </list> + <note> + <p> + You cannot make <em>any</em> assumptions about the + process that will perform the <c>apply()</c>. It may + be a server, or a freshly spawned process. + </p> + </note> + </desc> + </func> + + <func> + <name name="check_response" arity="2" since="OTP @OTP-13450@"/> + <fsummary>Check if a message is a response corresponding to a + previously sent call request.</fsummary> + <desc> + <p> + Check if a message is a response to a <c>call</c> request + previously made by the calling process using + <seealso marker="#send_request/4"><c>erpc:send_request/4</c></seealso>. + <c><anno>RequestId</anno></c> should be the value returned + from the previously made <c>erpc:send_request()</c> call, + and the corresponding response should not already have been + received and handled to completion by <c>erpc:check_response()</c>, + <seealso marker="#receive_response/2"><c>erpc:receive_response()</c></seealso>, or + <seealso marker="#wait_response/2"><c>erpc:wait_response()</c></seealso>. + <c><anno>Message</anno></c> is the message to check. + </p> + <p> + If <c><anno>Message</anno></c> does not correspond to the + response, the atom <c>no_response</c> is returned. If + <c><anno>Message</anno></c> corresponds to the response, the + <c>call</c> operation is completed and either the result is + returned as <c>{response, Result}</c> where <c>Result</c> + corresponds to the value returned from the applied function + or an exception is raised. The exceptions that can be raised + corresponds to the same exceptions as can be raised by + <seealso marker="#call/4"><c>erpc:call/4</c></seealso>. + That is, no <c>{erpc, timeout}</c> <c>error</c> exception + can be raised. + </p> + <p> + If the <c>erpc</c> operation fails, but it is unknown if + the function is/will be applied (that is, a connection loss), + the caller will not receive any further information about the + result if/when the applied function completes. If the applied + function explicitly communicates with the calling process, + such communication may, of course, reach the calling process. + </p> + </desc> + </func> + + <func> + <name name="multicall" arity="4" since="OTP @OTP-13450@"/> + <name name="multicall" arity="5" since="OTP @OTP-13450@"/> + <fsummary>Evaluate a function call on a number of nodes.</fsummary> + <type name="caught_call_exception"/> + <type name="stack_item"/> + <desc> + <p> + Performs multiple <c>call</c> operations in parallel + on multiple nodes. The result is returned as a list where + the result from each node is placed at the same position + as the node name is placed in <c><anno>Nodes</anno></c>. + Each item in the resulting list is formatted as either: + </p> + <taglist> + <tag><c>{ok, Result}</c></tag> + <item><p> + The <c>call</c> operation for this specific node + returned <c>Result</c>. + </p></item> + <tag><c>{Class, ExceptionReason}</c></tag> + <item><p> + The <c>call</c> operation for this specific node + raised an exception of class <c>Class</c> with + exception reason <c>ExceptionReason</c>. These + corresponds the the exceptions that + <seealso marker="#call/5"><c>erpc:call/5</c></seealso> + can raise. + </p></item> + </taglist> + <p> + The call <c>erpc:multicall(<anno>Nodes</anno>, <anno>Module</anno>, + <anno>Function</anno>, <anno>Args</anno>)</c> is equivalent + to the call <c>erpc:multicall(<anno>Nodes</anno>, <anno>Module</anno>, + <anno>Function</anno>, <anno>Args</anno>, infinity)</c>. These + calls are also equivalent to calling <c>my_multicall(Nodes, Module, + Function, Args)</c> if one disregards performance: + </p> + <pre> +my_multicall(Nodes, Module, Function, Args) -> + ReqIds = lists:map(fun (Node) -> + <seealso marker="#send_request/4">erpc:send_request(Node, Module, Function, Args)</seealso> + end, + Nodes), + lists:map(fun (ReqId) -> + try + {ok, <seealso marker="#receive_response/2">erpc:receive_response(ReqId, infinity)</seealso>} + catch + Class:Reason -> + {Class, Reason} + end + end, + ReqIds). +</pre> + + <p> + The <c><anno>Timeout</anno></c> value in milliseconds + sets an upper time limit for all <c>call</c> operations + to complete. + </p> + + <p> + If an <c>erpc</c> operation fails, but it is unknown if + the function is/will be applied (that is, a timeout or + connection loss), the caller will not receive any + further information about the result if/when the applied + function completes. If the applied function communicates + with the calling process, such communication may, of + course, reach the calling process. + </p> + </desc> + + </func> + + <func> + <name name="receive_response" arity="1" since="OTP @OTP-13450@"/> + <name name="receive_response" arity="2" since="OTP @OTP-13450@"/> + <fsummary>Receive a call response corresponding to a + previously sent call request.</fsummary> + <desc> + <p> + Receive a response to a <c>call</c> request previously + made by the calling process using + <seealso marker="#send_request/4"><c>erpc:send_request/4</c></seealso>. + <c><anno>RequestId</anno></c> should be the value returned from + the previously made <c>erpc:send_request()</c> call, and + the corresponding response should not already have been received + and handled to completion by + <seealso marker="#check_response/2"><c>erpc:check_response()</c></seealso>, + <c>erpc:receive_response()</c>, or + <seealso marker="#wait_response/2"><c>erpc:wait_response()</c></seealso>. + <c><anno>Timeout</anno></c> equals the timeout time in milliseconds + or the atom <c>infinity</c>. The <c>call</c> operation is completed + once the <c>erpc:receive_response()</c> call returns or raise an + exception. + </p> + <p> + The call <c>erpc:receive_response(<anno>RequestId</anno>)</c> is + equivalent to the call + <c>erpc:receive_response(<anno>RequestId</anno>, infinity)</c>. + </p> + <p> + A call to the function + <c>my_call(Node, Module, Function, Args, Timeout)</c> + below is equivalent to the call + <seealso marker="#call/5"><c>erpc:call(Node, Module, Function, Args, + Timeout)</c></seealso> if one disregards performance. <c>erpc:call()</c> + can utilize a message queue optimization which removes the need to scan + the whole message queue which the combination + <c>erpc:send_request()/erpc:receive_response()</c> cannot. + </p> + <pre> +my_call(Node, Module, Function, Args, Timeout) -> + RequestId = <seealso marker="#send_request/4">erpc:send_request(Node, Module, Function, Args)</seealso>, + erpc:receive_response(RequestId, Timeout). +</pre> + <p> + If the <c>erpc</c> operation fails, but it is unknown if + the function is/will be applied (that is, a timeout, or + a connection loss), the caller will not receive any + further information about the result if/when the applied + function completes. If the applied function explicitly + communicates with the calling process, such communication + may, of course, reach the calling process. + </p> + + <p> + <c>erpc:receive_response()</c> will return or raise exceptions the + same way as <seealso marker="#call/5"><c>erpc:call/5</c></seealso> + does. + </p> + </desc> + </func> + + <func> + <name name="send_request" arity="4" since="OTP @OTP-13450@"/> + <fsummary>Send a request to evaluate a function call on a node.</fsummary> + <desc> + <p> + Send an asynchronous <c>call</c> request to the node + <c><anno>Node</anno></c>. <c>erpc:send_request()</c> + returns a request identifier that later is to be passed + as argument to either + <seealso marker="#receive_response/1"><c>erpc:receive_response()</c></seealso>, + <seealso marker="#wait_response/1"><c>erpc:wait_response()</c></seealso>, + or, + <seealso marker="#check_response/2"><c>erpc:check_response()</c></seealso> + in order to get the response of the call request. + </p> + <p><c>erpc:send_request()</c> fails with an <c>{erpc, badarg}</c> + <c>error</c> exception if:</p> + <list> + <item><p><c><anno>Node</anno></c> is not a valid + node name atom.</p></item> + <item><p><c><anno>Module</anno></c> is not an atom.</p></item> + <item><p><c><anno>Function</anno></c> is not an atom.</p></item> + <item><p><c><anno>Args</anno></c> is not a proper list + of terms.</p></item> + </list> + </desc> + </func> + + <func> + <name name="wait_response" arity="1" since="OTP @OTP-13450@"/> + <name name="wait_response" arity="2" since="OTP @OTP-13450@"/> + <fsummary>Wait or poll for a call response corresponding to a previously + sent call request.</fsummary> + <desc> + <p> + Wait or poll for a response message to a <c>call</c> request + previously made by the calling process using + <seealso marker="#send_request/4"><c>erpc:send_request/4</c></seealso>. + <c><anno>RequestId</anno></c> should be the value returned from + the previously made <c>erpc:send_request()</c> call, and the + corresponding response should not already have been received and handled + to completion by + <seealso marker="#check_response/2"><c>erpc:check_response()</c></seealso>, + <seealso marker="#receive_response/2"><c>erpc:receive_response()</c></seealso>, + or <c>erpc:wait_response()</c>. <c><anno>WaitTime</anno></c> equals the + time to wait in milliseconds (or the atom <c>infinity</c>) during the wait. + </p> + <p> + The call <c>erpc:wait_response(<anno>RequestId</anno>)</c> is equivalent + to the call <c>erpc:wait_response(<anno>RequestId</anno>, 0)</c>. That is, + poll for a response message to a <c>call</c> request previously made by + the calling process. + </p> + <p> + If no response is received before <c><anno>WaitTime</anno></c> milliseconds, + the atom <c>no_response</c> is returned. It is valid to continue waiting + for a response as many times as needed up until a response has + been received and completed by <c>erpc:check_response()</c>, + <c>erpc:receive_response()</c>, or <c>erpc:wait_response()</c>. If a + response is received, the <c>call</c> operation is completed and either + the result is returned as <c>{response, Result}</c> where <c>Result</c> + corresponds to the value returned from the applied function or an + exception is raised. The exceptions that can be raised corresponds to the + same exceptions as can be raised by + <seealso marker="#call/4"><c>erpc:call/4</c></seealso>. + That is, no <c>{erpc, timeout}</c> <c>error</c> exception can be raised. + </p> + <p> + If the <c>erpc</c> operation fails, but it is unknown if + the function is/will be applied (that is, a too large wait time + value, or a connection loss), the caller will not receive any + further information about the result if/when the applied function + completes. If the applied function explicitly communicates with the + calling process, such communication may, of course, reach the + calling process. + </p> + </desc> + </func> + + </funcs> +</erlref> + diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml index fc25e83d40..c4073f13a2 100644 --- a/lib/kernel/doc/src/file.xml +++ b/lib/kernel/doc/src/file.xml @@ -202,10 +202,7 @@ <desc> <p><c>allocate/3</c> can be used to preallocate space for a file.</p> <p>This function only succeeds in platforms that provide this - feature. When it succeeds, space is preallocated for the file but - the file size might not be updated. This behaviour depends on the - preallocation implementation. To guarantee that the file size is updated, - truncate the file to the new size.</p> + feature.</p> </desc> </func> <func> @@ -939,6 +936,10 @@ f.txt: {person, "kalle", 25}. support for POSIX <c>O_SYNC</c> or equivalent, use of the <c>sync</c> flag causes <c>open</c> to return <c>{error, enotsup}</c>.</p> </item> + <tag><c>directory</c></tag> + <item> + <p>Allows <c>open</c> to work on directories.</p> + </item> </taglist> <p>Returns:</p> <taglist> @@ -953,10 +954,9 @@ f.txt: {person, "kalle", 25}. </item> </taglist> <p><c><anno>IoDevice</anno></c> is really the pid of the process that - handles the file. This process is linked to the process - that originally opened the file. If any process to which - the <c><anno>IoDevice</anno></c> is linked terminates, the file is - closed and the process itself is terminated. + handles the file. This process monitors the process that originally + opened the file (the owner process). If the owner process terminates, + the file is closed and the process itself terminates too. An <c><anno>IoDevice</anno></c> returned from this call can be used as an argument to the I/O functions (see <seealso marker="stdlib:io"><c>io(3)</c></seealso>).</p> @@ -985,8 +985,10 @@ f.txt: {person, "kalle", 25}. </item> <tag><c>enotdir</c></tag> <item> - <p>A component of the filename is not a directory. On some - platforms, <c>enoent</c> is returned instead.</p> + <p>A component of the filename is not a directory, or the + filename itself is not a directory if <c>directory</c> + mode was specified. On some platforms, <c>enoent</c> is + returned instead.</p> </item> <tag><c>enospc</c></tag> <item> @@ -1438,7 +1440,11 @@ f.txt: {person, "kalle", 25}. break this module's atomicity guarantees as it can race with a concurrent call to <seealso marker="#write_file_info/2"><c>write_file_info/1,2</c> - </seealso></p> + </seealso>.</p> + <p>This option has no effect when the function is + given an I/O device instead of a file name. Use + <seealso marker="#open/2"><c>open/2</c></seealso> with the + <c>raw</c> mode to obtain a file descriptor first.</p> <note> <p>As file times are stored in POSIX time on most OS, it is faster to query file information with option <c>posix</c>.</p> diff --git a/lib/kernel/doc/src/gen_sctp.xml b/lib/kernel/doc/src/gen_sctp.xml index 61ac1485c1..d9194da4f2 100644 --- a/lib/kernel/doc/src/gen_sctp.xml +++ b/lib/kernel/doc/src/gen_sctp.xml @@ -165,7 +165,7 @@ <pre> #sctp_assoc_change{ state = atom(), - error = atom(), + error = integer(), outbound_streams = integer(), inbound_streams = integer(), assoc_id = assoc_id() @@ -208,7 +208,9 @@ connect(Socket, Ip, Port>, <tag><c>shutdown_comp</c></tag> <item></item> </taglist> - <p>Field <c>error</c> can provide more detailed diagnostics.</p> + <p>Field <c>error</c> can provide more detailed diagnostics. + The <c>error</c> field value can be converted into a string using + <seealso marker="#error_string/1"><c>error_string/1</c></seealso>.</p> </desc> </func> diff --git a/lib/kernel/doc/src/gen_udp.xml b/lib/kernel/doc/src/gen_udp.xml index 14819aa938..9ecadc5498 100644 --- a/lib/kernel/doc/src/gen_udp.xml +++ b/lib/kernel/doc/src/gen_udp.xml @@ -305,4 +305,3 @@ </func> </funcs> </erlref> - diff --git a/lib/kernel/doc/src/kernel_app.xml b/lib/kernel/doc/src/kernel_app.xml index 7f9609d5c1..7ad3d15cd6 100644 --- a/lib/kernel/doc/src/kernel_app.xml +++ b/lib/kernel/doc/src/kernel_app.xml @@ -414,6 +414,15 @@ MaxT = TickTime + TickTime / 4</code> using this service.</p> <p>Defaults to <c>false</c>.</p> </item> + <tag><c>start_pg = true | false</c></tag> + <item> + <marker id="start_pg"></marker> + <p>Starts the default <c>pg</c> scope server (see + <seealso marker="pg"><c>pg(3)</c></seealso>) if + the parameter is <c>true</c>. This parameter is to be set to + <c>true</c> in an embedded system that uses this service.</p> + <p>Defaults to <c>false</c>.</p> + </item> <tag><c>start_pg2 = true | false</c></tag> <item> <marker id="start_pg2"></marker> @@ -556,6 +565,7 @@ erl -kernel logger '[{handler,default,logger_std_h,#{formatter=>{logger_formatte <seealso marker="logger"><c>logger(3)</c></seealso>, <seealso marker="net_kernel"><c>net_kernel(3)</c></seealso>, <seealso marker="os"><c>os(3)</c></seealso>, + <seealso marker="pg"><c>pg(3)</c></seealso>, <seealso marker="pg2"><c>pg2(3)</c></seealso>, <seealso marker="rpc"><c>rpc(3)</c></seealso>, <seealso marker="seq_trace"><c>seq_trace(3)</c></seealso>, diff --git a/lib/kernel/doc/src/net.xml b/lib/kernel/doc/src/net.xml index d60e1af311..d7732e714a 100644 --- a/lib/kernel/doc/src/net.xml +++ b/lib/kernel/doc/src/net.xml @@ -122,7 +122,7 @@ <funcs> <func> - <name name="gethostname" arity="0"/> + <name name="gethostname" arity="0" since="OTP 22.0"/> <fsummary>Get hostname.</fsummary> <desc> <p>Returns the name of the current host.</p> diff --git a/lib/kernel/doc/src/pg.xml b/lib/kernel/doc/src/pg.xml new file mode 100644 index 0000000000..f04d9561e9 --- /dev/null +++ b/lib/kernel/doc/src/pg.xml @@ -0,0 +1,195 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<!-- %ExternalCopyright% --> + +<erlref> + <header> + <copyright> + <year>2020</year><year>2020</year> + <holder>Maxim Fedorov, WhatsApp Inc.</holder> + </copyright> + <legalnotice> + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + </legalnotice> + + <title>pg</title> + <prepared>maximfca@gmail.com</prepared> + <responsible></responsible> + <docno></docno> + <approved></approved> + <checked></checked> + <date></date> + <rev>A</rev> + <file>pg.xml</file> + </header> + <module since="OTP 23.0">pg</module> + <modulesummary>Distributed named process groups.</modulesummary> + <description> + <p>This module implements process groups. A message can be sent + to one, some, or all group members.</p> + + <p>Up until OTP 17 there used to exist an experimental <c>pg</c> + module in <c>stdlib</c>. This <c>pg</c> module is not the same + module as that experimental <c>pg</c> module, and only share + the same module name.</p> + + <p>A group of processes can be accessed by a common name. For + example, if there is a group named <c>foobar</c>, there can be a + set of processes (which can be located on different nodes) that + are all members of the group <c>foobar</c>. There are no special + functions for sending a message to the group. Instead, client + functions are to be written with the functions + <seealso marker="#get_members/1"><c>get_members/1</c></seealso> and + <seealso marker="#get_local_members/1"><c>get_local_members/1</c></seealso> + to determine which processes are members of the group. + Then the message can be sent to one or more group members.</p> + <p>If a member terminates, it is automatically removed from the group.</p> + + <p>A process may join multiple groups. It may join the same group multiple times. + It is only allowed to join processes running on local node. + </p> + + <p>Process Groups implement strong eventual consistency. + Unlike <seealso marker="pg2"><c>pg2</c></seealso>, that provides + strong ordering guarantees, Process Groups membership view may temporarily + diverge. For example, when processes on <c>node1</c> and <c>node2</c> + join concurrently, <c>node3</c> and <c>node4</c> may receive updates in + a different order.</p> + + <p> Membership view is not transitive. If <c>node1</c> is not directly + connected to <c>node2</c>, they will not see each other groups. But if + both are connected to <c>node3</c>, <c>node3</c> will have the full view. </p> + + <p>Groups are automatically created when any process joins, + and are removed when all processes leave the group. Non-existing group is + considered empty (containing no processes).</p> + + <p>Process groups can be organised into multiple scopes. Scopes are + completely independent of each other. A process may join any + number of groups in any number of scopes. Scopes are designed to + decouple single mesh into a set of overlay networks, reducing + amount of traffic required to propagate group membership + information. Default scope <c>pg</c> is started automatically + when <seealso marker="kernel_app#start_pg"><c>kernel(6)</c></seealso> + is configured to do so. + </p> + + <note><p> + Scope name is used to register process locally, and to name an ETS table. + If there is another process registered under this name, or another ETS table + exists, scope fails to start.</p> + <p>Local membership is not preserved if scope process exits and + restarts. This behaviour is different from + <seealso marker="pg2"><c>pg2</c></seealso>, that recovers + local membership from remote nodes. + </p></note> + + </description> + + <datatypes> + <datatype> + <name name="group"/> + <desc><p>The identifier of a process group.</p></desc> + </datatype> + </datatypes> + + <funcs> + + <func> + <name name="start_link" arity="0" since="OTP 23.0"/> + <fsummary>Start the default <c>pg</c> scope.</fsummary> + <desc> + <p>Starts the default <c>pg</c> scope within supervision tree. + Kernel may be configured to do it automatically, see + <seealso marker="kernel_app#start_pg"><c>kernel(6)</c></seealso> + configuration manual.</p> + </desc> + </func> + + <func> + <name name="start" arity="1" since="OTP 23.0"/> + <name name="start_link" arity="1" since="OTP 23.0"/> + <fsummary>Start additional scope.</fsummary> + <desc> + <p>Starts additional scope.</p> + </desc> + </func> + + <func> + <name name="join" arity="2" since="OTP 23.0"/> + <name name="join" arity="3" since="OTP 23.0"/> + <fsummary>Join a process or a list of processes to a group.</fsummary> + <desc> + <p>Joins single process or multiple processes to the + group <c>Name</c>. A process can join a group many times and + must then leave the group the same number of times.</p> + <p><c>PidOrPids</c> may contain the same process multiple times.</p> + </desc> + </func> + + <func> + <name name="leave" arity="2" since="OTP 23.0"/> + <name name="leave" arity="3" since="OTP 23.0"/> + <fsummary>Make a process leave a group.</fsummary> + <desc> + <p>Makes the process <c>PidOrPids</c> leave the group <c>Name</c>. + If the process is not a member of the group, <c>not_joined</c> is + returned.</p> + <p>When list of processes is passed as <c>PidOrPids</c>, function + returns <c>not_joined</c> only when all processes of the list + are not joined.</p> + </desc> + </func> + + <func> + <name name="get_local_members" arity="1" since="OTP 23.0"/> + <name name="get_local_members" arity="2" since="OTP 23.0"/> + <fsummary>Return all local processes in a group.</fsummary> + <desc> + <p>Returns all processes running on the local node in the + group <c>Name</c>. Processes are returned in no specific order. + This function is optimised for speed. + </p> + </desc> + </func> + + <func> + <name name="get_members" arity="1" since="OTP 23.0"/> + <name name="get_members" arity="2" since="OTP 23.0"/> + <fsummary>Return all processes in a group.</fsummary> + <desc> + <p>Returns all processes in the group <c>Name</c>. + Processes are returned in no specific order. + This function is optimised for speed.</p> + </desc> + </func> + + <func> + <name name="which_groups" arity="0" since="OTP 23.0"/> + <name name="which_groups" arity="1" since="OTP 23.0"/> + <fsummary>Return a list of all known groups.</fsummary> + <desc> + <p>Returns a list of all known groups.</p> + </desc> + </func> + + </funcs> + + <section> + <title>See Also</title> + <p><seealso marker="kernel_app"><c>kernel(6)</c></seealso></p> + </section> +</erlref> + diff --git a/lib/kernel/doc/src/pg2.xml b/lib/kernel/doc/src/pg2.xml index 058d711756..510dea0b92 100644 --- a/lib/kernel/doc/src/pg2.xml +++ b/lib/kernel/doc/src/pg2.xml @@ -35,6 +35,16 @@ <module since="">pg2</module> <modulesummary>Distributed named process groups.</modulesummary> <description> + <warning> + <p> + The <c>pg2</c> module is deprecated as of OTP 23 and scheduled + for removal in OTP 24. You are advised to replace the usage of + <c>pg2</c> with <seealso marker="kernel:pg">pg</seealso>. + <c>pg</c> has a similar API, but with an implementation that + is more scalable. See the documentation of <c>pg</c> for more + information about differences. + </p> + </warning> <p>This module implements process groups. Each message can be sent to one, some, or all group members.</p> <p>A group of processes can be accessed by a common name. For diff --git a/lib/kernel/doc/src/ref_man.xml b/lib/kernel/doc/src/ref_man.xml index 9df51dee22..9127157eb5 100644 --- a/lib/kernel/doc/src/ref_man.xml +++ b/lib/kernel/doc/src/ref_man.xml @@ -43,6 +43,7 @@ <xi:include href="erl_epmd.xml"/> <xi:include href="erl_prim_loader_stub.xml"/> <xi:include href="erlang_stub.xml"/> + <xi:include href="erpc.xml"/> <xi:include href="error_handler.xml"/> <xi:include href="error_logger.xml"/> <xi:include href="file.xml"/> @@ -64,6 +65,7 @@ <xi:include href="net_adm.xml"/> <xi:include href="net_kernel.xml"/> <xi:include href="os.xml"/> + <xi:include href="pg.xml"/> <xi:include href="pg2.xml"/> <xi:include href="rpc.xml"/> <xi:include href="seq_trace.xml"/> diff --git a/lib/kernel/doc/src/rpc.xml b/lib/kernel/doc/src/rpc.xml index 0e07d334d8..03bfc97c5b 100644 --- a/lib/kernel/doc/src/rpc.xml +++ b/lib/kernel/doc/src/rpc.xml @@ -37,13 +37,29 @@ a function on a remote node and collect the answer. It is used for collecting information on a remote node, or for running a function with some specific side effects on the remote node.</p> + <note><p> + <c>rpc:call()</c> and friends makes it quite hard to distinguish + between successful results, raised exceptions, and other errors. + This cannot be changed due to compatibility reasons. As of OTP 23, + a new module <seealso marker="erpc"><c>erpc</c></seealso> was + introduced in order to provide an API that makes it possible + to distingush between the different results. The <c>erpc</c> + module provides a subset (however, the central subset) of the + functionality available in the <c>rpc</c> module. The <c>erpc</c> + implementation also provides a more scalable implementation with + better performance than the original <c>rpc</c> implementation. + However, since the introduction of <c>erpc</c>, the <c>rpc</c> + module implements large parts of its central functionality using + <c>erpc</c>, so the <c>rpc</c> module wont not suffer scalability + wise and performance wise compared to <c>erpc</c>. + </p></note> </description> <datatypes> <datatype> <name name="key"/> <desc> - <p>As returned by + <p>Opaque value returned by <seealso marker="#async_call/4"><c>async_call/4</c></seealso>.</p> </desc> </datatype> @@ -87,7 +103,17 @@ <seealso marker="#nb_yield/1"><c>nb_yield/1,2</c></seealso> to retrieve the value of evaluating <c>apply(<anno>Module</anno>, <anno>Function</anno>, <anno>Args</anno>)</c> on node - <c><anno>Node</anno></c>.</p> + <c><anno>Node</anno></c>.</p> + <note> + <p> + If you want the ability to distinguish between results, + you may want to consider using the + <seealso marker="erpc#send_request/4"><c>erpc:send_request()</c></seealso> + function from the <c>erpc</c> module instead. This also + gives you the ability retrieve the results in other useful + ways. + </p> + </note> <note> <p><seealso marker="#yield/1"><c>yield/1</c></seealso> and <seealso marker="#nb_yield/1"><c>nb_yield/1,2</c></seealso> @@ -99,34 +125,34 @@ <func> <name name="block_call" arity="4" since=""/> - <fsummary>Evaluate a function call on a node in the RPC server's - context.</fsummary> - <desc> - <p>Same as <seealso marker="#call/4"><c>call/4</c></seealso>, - but the RPC server at <c><anno>Node</anno></c> does - not create a separate process to handle the call. Thus, - this function can be used if the intention of the call is to - block the RPC server from any other incoming requests until - the request has been handled. The function can also be used - for efficiency reasons when very small fast functions are - evaluated, for example, BIFs that are guaranteed not to - suspend.</p> - <p>See the note in <seealso marker="#call/4"><c>call/4</c></seealso> - for more details of the return value.</p> + <fsummary>Evaluate a function call on a node.</fsummary> + <desc> + <p> + The same as calling + <seealso marker="#block_call/5"><c>rpc:block_call(<anno>Node</anno>, + <anno>Module</anno>, <anno>Function</anno>, + <anno>Args</anno>, infinity)</c></seealso>. + </p> </desc> </func> <func> <name name="block_call" arity="5" since=""/> - <fsummary>Evaluate a function call on a node in the RPC server's - context.</fsummary> + <fsummary>Evaluate a function call on a node.</fsummary> <desc> - <p>Same as - <seealso marker="#block_call/4"><c>block_call/4</c></seealso>, - but with a time-out value in the same manner as - <seealso marker="#call/5"><c>call/5</c></seealso>.</p> - <p>See the note in <seealso marker="#call/4"><c>call/4</c></seealso> - for more details of the return value.</p> + <p> + The same as calling + <seealso marker="#call/5"><c>rpc:call(<anno>Node</anno>, + <anno>Module</anno>, <anno>Function</anno>, + <anno>Args</anno>, <anno>Timeout</anno>)</c></seealso> with + the exception that it also blocks other <c>rpc:block_call()</c> + operations from executing concurrently on the node + <c><anno>Node</anno></c>. + </p> + <warning><p> + Note that it also blocks other operations than just + <c>rpc:block_call()</c> operations, so use it with care. + </p></warning> </desc> </func> @@ -135,9 +161,38 @@ <fsummary>Evaluate a function call on a node.</fsummary> <desc> <p>Evaluates <c>apply(<anno>Module</anno>, <anno>Function</anno>, + <anno>Args</anno>)</c> on node <c><anno>Node</anno></c> and returns + the corresponding value <c><anno>Res</anno></c>, or + <c>{badrpc, <anno>Reason</anno>}</c> if the call fails. + The same as calling + <seealso marker="#call/5"><c>rpc:call(<anno>Node</anno>, + <anno>Module</anno>, <anno>Function</anno>, + <anno>Args</anno>, infinity)</c></seealso>. + </p> + </desc> + </func> + + <func> + <name name="call" arity="5" since=""/> + <fsummary>Evaluate a function call on a node.</fsummary> + <desc> + <p>Evaluates <c>apply(<anno>Module</anno>, <anno>Function</anno>, <anno>Args</anno>)</c> on node <c><anno>Node</anno></c> and returns the corresponding value <c><anno>Res</anno></c>, or - <c>{badrpc, <anno>Reason</anno>}</c> if the call fails.</p> + <c>{badrpc, <anno>Reason</anno>}</c> if the call fails. + <c><anno>Timeout</anno></c> is + a time-out value in milliseconds. If the call times out, + <c><anno>Reason</anno></c> is <c>timeout</c>.</p> + <p>If the reply arrives after the call times out, no message + contaminates the caller's message queue.</p> + <note> + <p> + If you want the ability to distinguish between results, + you may want to consider using the + <seealso marker="erpc#call/4"><c>erpc:call()</c></seealso> + function from the <c>erpc</c> module instead. + </p> + </note> <note> <p>Here follows the details of what exactly is returned.</p> <p><c>{badrpc, <anno>Reason</anno>}</c> will be returned in the @@ -159,28 +214,14 @@ <strong>not</strong> match <c>{'EXIT',_}</c>.</item> </list> </note> - </desc> - </func> - - <func> - <name name="call" arity="5" since=""/> - <fsummary>Evaluate a function call on a node.</fsummary> - <desc> - <p>Evaluates <c>apply(<anno>Module</anno>, <anno>Function</anno>, - <anno>Args</anno>)</c> on node <c><anno>Node</anno></c> and returns - the corresponding value <c><anno>Res</anno></c>, or - <c>{badrpc, <anno>Reason</anno>}</c> if the call fails. - <c><anno>Timeout</anno></c> is - a time-out value in milliseconds. If the call times out, - <c><anno>Reason</anno></c> is <c>timeout</c>. - See the note in <seealso marker="#call/4"><c>call/4</c></seealso> - for more details of the return value.</p> - <p>If the reply arrives after the call times out, no message - contaminates the caller's message queue, as this - function spawns off a middleman process to act as (a void) - destination for such an orphan reply. This feature also makes - this function more expensive than <c>call/4</c> at - the caller's end.</p> + <note> + <p> + You cannot make <em>any</em> assumptions about the + process that will perform the <c>apply()</c>. It may + be the calling process itself, an <c>rpc</c> server, + another server, or a freshly spawned process. + </p> + </note> </desc> </func> @@ -194,6 +235,14 @@ process is not suspended until the evaluation is complete, as is the case with <seealso marker="#call/4"><c>call/4,5</c></seealso>.</p> + <note> + <p> + You cannot make <em>any</em> assumptions about the + process that will perform the <c>apply()</c>. It may + be an <c>rpc</c> server, another server, or a + freshly spawned process. + </p> + </note> </desc> </func> @@ -226,7 +275,7 @@ <anno>Name</anno>, <anno>Msg</anno>)</c>.</p> </desc> </func> - + <func> <name name="multi_server_call" arity="3" since=""/> <fsummary>Interact with the servers on a number of nodes.</fsummary> @@ -311,6 +360,14 @@ {ResL, _} = rpc:multicall(code, load_binary, [Mod, File, Bin]), %% and then maybe check the ResL list.</code> + <note> + <p> + If you want the ability to distinguish between results, + you may want to consider using the + <seealso marker="erpc#multicall/4"><c>erpc:multicall()</c></seealso> + function from the <c>erpc</c> module instead. + </p> + </note> </desc> </func> diff --git a/lib/kernel/doc/src/seq_trace.xml b/lib/kernel/doc/src/seq_trace.xml index 9aef748594..059f03593f 100644 --- a/lib/kernel/doc/src/seq_trace.xml +++ b/lib/kernel/doc/src/seq_trace.xml @@ -29,10 +29,11 @@ <rev>A</rev> </header> <module since="">seq_trace</module> - <modulesummary>Sequential tracing of messages.</modulesummary> + <modulesummary>Sequential tracing of information transfers.</modulesummary> <description> - <p>Sequential tracing makes it possible to trace all messages - resulting from one initial message. Sequential tracing is + <p>Sequential tracing makes it possible to trace information + flows between processes resulting from one initial transfer + of information. Sequential tracing is independent of the ordinary tracing in Erlang, which is controlled by the <c>erlang:trace/3</c> BIF. For more information about what sequential tracing is and how it can be used, see section @@ -104,13 +105,13 @@ seq_trace:set_token(OldToken), % activate the trace token again <tag><c>set_token(send, <anno>Bool</anno>)</c></tag> <item> <p>A trace token flag (<c>true | false</c>) which - enables/disables tracing on message sending. Default is + enables/disables tracing on information sending. Default is <c>false</c>.</p> </item> <tag><c>set_token('receive', <anno>Bool</anno>)</c></tag> <item> <p>A trace token flag (<c>true | false</c>) which - enables/disables tracing on message reception. Default is + enables/disables tracing on information reception. Default is <c>false</c>.</p> </item> <tag><c>set_token(print, <anno>Bool</anno>)</c></tag> @@ -257,12 +258,26 @@ TimeStamp = {Seconds, Milliseconds, Microseconds} <tag><c>{send, Serial, From, To, Message}</c></tag> <item> <p>Used when a process <c>From</c> with its trace token flag - <c>send</c> set to <c>true</c> has sent a message.</p> + <c>send</c> set to <c>true</c> has sent information. <c>To</c> + may be a process identifier, a registered name on a node + represented as <c>{NameAtom, NodeAtom}</c>, or a node name + represented as an atom. <c>From</c> may be a process identifier + or a node name represented as an atom. <c>Message</c> contains + the information passed along in this information transfer. If + the transfer is done via message passing, it is the actual + message. + </p> </item> <tag><c>{'receive', Serial, From, To, Message}</c></tag> <item> - <p>Used when a process <c>To</c> receives a message with a - trace token that has flag <c>'receive'</c> set to <c>true</c>.</p> + <p>Used when a process <c>To</c> receives information with a + trace token that has flag <c>'receive'</c> set to <c>true</c>. + <c>To</c> may be a process identifier, or a node name + represented as an atom. <c>From</c> may be a process identifier + or a node name represented as an atom. <c>Message</c> contains + the information passed along in this information transfer. If + the transfer is done via message passing, it is the actual + message.</p> </item> <tag><c>{print, Serial, From, _, Info}</c></tag> <item> @@ -276,7 +291,7 @@ TimeStamp = {Seconds, Milliseconds, Microseconds} where:</p> <list type="bulleted"> <item><p>Integer <c>PreviousSerial</c> denotes the serial - counter passed in the last received message that carried a trace + counter passed in the last received information that carried a trace token. If the process is the first in a new sequential trace, <c>PreviousSerial</c> is set to the value of the process internal "trace clock".</p></item> @@ -290,22 +305,32 @@ TimeStamp = {Seconds, Milliseconds, Microseconds} <section> <marker id="whatis"></marker> <title>Sequential Tracing</title> - <p>Sequential tracing is a way to trace a sequence of messages sent - between different local or remote processes, where the sequence - is initiated by a single message. In short, it works as follows:</p> + <p>Sequential tracing is a way to trace a sequence of information + transfers between different local or remote processes, where the + sequence is initiated by a single transfer. The typical information + transfer is an ordinary Erlang message passed between two processes, + but information is transferred also in other ways. In short, it works + as follows:</p> <p>Each process has a <em>trace token</em>, which can be empty or not empty. When not empty, the trace token can be seen as the tuple <c>{Label, Flags, Serial, From}</c>. The trace token is - passed invisibly with each message.</p> + passed invisibly when information is passed between processes. + In most cases the information is passed in ordinary messages + between processes, but information is also passed between processes + by other means. For example, by spawning a new process. An information + transfer between two processes is represented by a send event and a + receive event regardless of how it is passed. + </p> <p>To start a sequential trace, the user must explicitly set - the trace token in the process that will send the first message + the trace token in the process that will send the first information in a sequence.</p> <p>The trace token of a process is set each time the process + receives information. This is typically when the process matches a message in a receive statement, according to the trace token carried by the received message, empty or not.</p> <p>On each Erlang node, a process can be set as the <em>system tracer</em>. This process will receive trace messages each time - a message with a trace token is sent or received (if the trace + information with a trace token is sent or received (if the trace token flag <c>send</c> or <c>'receive'</c> is set). The system tracer can then print each trace event, write it to a file, or whatever suitable.</p> @@ -321,11 +346,58 @@ TimeStamp = {Seconds, Milliseconds, Microseconds} </section> <section> + <title>Different Information Transfers</title> + <p> + Information flows between processes in a lot of different + ways. Not all flows of information will be covered by + sequential tracing. One example is information passed via + ETS tables. Below is a list of information paths that are + covered by sequential tracing:</p> + <taglist> + <tag>Message Passing</tag> + <item><p> + All ordinary messages passed between Erlang processes. + </p></item> + <tag>Exit signals</tag> + <item><p> + An exit signal is represented as an <c>{'EXIT', Pid, Reason}</c> + tuple. + </p></item> + <tag>Process Spawn</tag> + <item><p> + A process spawn is represented as multiple information + transfers. At least one spawn request and one spawn reply. The + actual amount of information transfers depends on what type + of spawn it is and may also change in future implementations. + Note that this is more or less an internal protocol that you + are peeking at. The spawn request will be represented as a + tuple with the first element containing the atom + <c>spawn_request</c>, but this is more or less all that you + can depend on. + </p></item> + </taglist> + <note> + <p> + If you do ordinary <c>send</c> or <c>receive</c> + trace on the system, you will only see ordinary message + passing, not the other information transfers listed above. + </p> + </note> + <note> + <p> + When a send event and corresponding receive event do not + both correspond to ordinary Erlang messages, the <c>Message</c> + part of the trace messages may not be identical. This since + all information not necessarily are available when generating + the trace messages. + </p> + </note> + </section> + + <section> <title>Trace Token</title> - <p>Each process has a current trace token. Initially, the token is - empty. When the process sends a message to another process, a - copy of the current token is sent "invisibly" along with - the message.</p> + <p>Each process has a current trace token which is "invisibly" passed + from the parent process on creation of the process.</p> <p>The current token of a process is set in one of the following two ways:</p> <list type="bulleted"> @@ -334,7 +406,9 @@ TimeStamp = {Seconds, Milliseconds, Microseconds} <c>seq_trace:set_token/1,2</c></p> </item> <item> - <p>When a message is received</p> + <p>When information is received. This is typically when + a received message is matched out in a receive expression, + but also when information is received in other ways.</p> </item> </list> <p>In both cases, the current token is set. In particular, if @@ -354,12 +428,16 @@ TimeStamp = {Seconds, Milliseconds, Microseconds} <p>The algorithm for updating <c>Serial</c> can be described as follows:</p> <p>Let each process have two counters, <c>prev_cnt</c> and - <c>curr_cnt</c>, both are set to <c>0</c> when a process is created. - The counters are updated at the following occasions:</p> + <c>curr_cnt</c>, both are set to <c>0</c> when a process is created + outside of a trace sequence. The counters are updated at the following + occasions:</p> <list type="bulleted"> <item> - <p><em>When the process is about to send a message and the trace token - is not empty.</em></p> + <p><em>When the process is about to pass along information to + another process and the trace token is not empty.</em> This + typically occurs when sending a message, but also, for example, + when spawning another process. + </p> <p>Let the serial of the trace token be <c>tprev</c> and <c>tcurr</c>.</p> <pre> @@ -367,7 +445,7 @@ curr_cnt := curr_cnt + 1 tprev := prev_cnt tcurr := curr_cnt</pre> <p>The trace token with <c>tprev</c> and <c>tcurr</c> is then - passed along with the message.</p> + passed along with the information passed to the other process.</p> </item> <item> <p><em>When the process calls</em> <c>seq_trace:print(Label, Info)</c>, @@ -376,8 +454,9 @@ tcurr := curr_cnt</pre> <p>The algorithm is the same as for send above.</p> </item> <item> - <p><em>When a message is received and contains a non-empty trace - token.</em></p> + <p><em>When information is received that also contains a non-empty + trace token. For example, when a message is matched out in a + receive expression, or when a new process is spawned.</em></p> <p>The process trace token is set to the trace token from the message.</p> <p>Let the serial of the trace token be <c>tprev</c> and @@ -487,9 +566,9 @@ tracer() -> print_trace(Label,TraceInfo,false); {seq_trace,Label,TraceInfo,Ts} -> print_trace(Label,TraceInfo,Ts); - Other -> ignore + _Other -> ignore end, - tracer(). + tracer(). print_trace(Label,TraceInfo,false) -> io:format("~p:",[Label]), @@ -504,7 +583,7 @@ print_trace({'receive',Serial,From,To,Message}) -> io:format("~p Received ~p FROM ~p WITH~n~p~n", [To,Serial,From,Message]); print_trace({send,Serial,From,To,Message}) -> - io:format("~p Sent ~p TO ~p WITH~n~p~n", + io:format("~p Sent ~p TO ~p WITH~n~p~n", [From,Serial,To,Message]).</code> <p>The code that creates a process that runs this tracer function and sets that process as the system tracer can look like this:</p> diff --git a/lib/kernel/doc/src/specs.xml b/lib/kernel/doc/src/specs.xml index 9e258910db..00f6f04218 100644 --- a/lib/kernel/doc/src/specs.xml +++ b/lib/kernel/doc/src/specs.xml @@ -9,6 +9,7 @@ <xi:include href="../specs/specs_erl_epmd.xml"/> <xi:include href="../specs/specs_erl_prim_loader_stub.xml"/> <xi:include href="../specs/specs_erlang_stub.xml"/> + <xi:include href="../specs/specs_erpc.xml"/> <xi:include href="../specs/specs_error_handler.xml"/> <xi:include href="../specs/specs_error_logger.xml"/> <xi:include href="../specs/specs_file.xml"/> @@ -30,6 +31,7 @@ <xi:include href="../specs/specs_net_adm.xml"/> <xi:include href="../specs/specs_net_kernel.xml"/> <xi:include href="../specs/specs_os.xml"/> + <xi:include href="../specs/specs_pg.xml"/> <xi:include href="../specs/specs_pg2.xml"/> <xi:include href="../specs/specs_rpc.xml"/> <xi:include href="../specs/specs_seq_trace.xml"/> |