You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by si...@apache.org on 2019/06/19 20:51:17 UTC

[pulsar] branch master updated: [Docs] Update site2/docs/functions-overview.md (#4507)

This is an automated email from the ASF dual-hosted git repository.

sijie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar.git


The following commit(s) were added to refs/heads/master by this push:
     new 4c38c9a  [Docs] Update site2/docs/functions-overview.md (#4507)
4c38c9a is described below

commit 4c38c9a9a6f1528613332f83804abb47d1d2dc2f
Author: Jennifer Huang <47...@users.noreply.github.com>
AuthorDate: Thu Jun 20 04:51:12 2019 +0800

    [Docs] Update site2/docs/functions-overview.md (#4507)
    
    ### Motivation
    Improve doc on Pulsar Functions.
    
    ### Modifications
    1. Add an example of Pulsar Function for Go.
    2. Add Pulsar Functions SDK: Go.
    3. Add an example of Go function logging.
    4. Refine a section title from "Parallelism" as "Run instances in parallel"
    5. Refine some typos.
    
    ### Documentation
    
      - Does this pull request introduce a new feature? (yes )
      - If yes, how is the feature documented? ( docs)
---
 site2/docs/functions-overview.md | 218 +++++++++++++++++++++++++--------------
 1 file changed, 139 insertions(+), 79 deletions(-)

diff --git a/site2/docs/functions-overview.md b/site2/docs/functions-overview.md
index 36acdc1..0f3769e 100644
--- a/site2/docs/functions-overview.md
+++ b/site2/docs/functions-overview.md
@@ -8,9 +8,9 @@ sidebar_label: Overview
 
 * consume messages from one or more Pulsar topics,
 * apply a user-supplied processing logic to each message,
-* publish the results of the computation to another topic
+* publish the results of the computation to another topic.
 
-Here's an example Pulsar Function for Java (using the [native interface](functions-api.md#java-native-functions)):
+The following is an example of a Pulsar Function written in Java (using the [native interface](functions-api.md#java-native-functions)).
 
 ```java
 import java.util.Function;
@@ -21,40 +21,58 @@ public class ExclamationFunction implements Function<String, String> {
 }
 ```
 
-Here's an equivalent function in Python (also using the [native interface](functions-api.md#python-native-functions)):
+The following is an example of a Pulsar Function written in Python (using the [native interface](functions-api.md#python-native-functions)).
 
 ```python
 def process(input):
     return "{0}!".format(input)
 ```
+The following is an example of a Pulsar Function written in Go.
 
-Functions are executed each time a message is published to the input topic. If a function is listening on the topic `tweet-stream`, for example, then the function would be run each time a message is published to that topic.
+```
+import (
+	"fmt"
+	"context"
+
+	"github.com/apache/pulsar/pulsar-function-go/pf"
+)
+
+func HandleRequest(ctx context.Context, in []byte) error {
+	fmt.Println(string(in) + "!")
+	return nil
+}
+
+func main() {
+	pf.Start(HandleRequest)
+}
+```
+
+A Pulsar Function is executed each time a message is published to its input topic. For example, if a function has an input topic called `tweet-stream`, the function runs each time a message is published to `tweet-stream`.
 
 ## Goals
 
-The core goal behind Pulsar Functions is to enable you to easily create processing logic of any level of complexity without needing to deploy a separate neighboring system (such as [Apache Storm](http://storm.apache.org/), [Apache Heron](https://apache.github.io/incubator-heron), [Apache Flink](https://flink.apache.org/), etc.). Pulsar Functions is essentially ready-made compute infrastructure at your disposal as part of your Pulsar messaging system. This core goal is tied to a series of [...]
+With Pulsar Functions, you can create complex processing logic without deploying a separate neighboring system (such as [Apache Storm](http://storm.apache.org/), [Apache Heron](https://apache.github.io/incubator-heron), [Apache Flink](https://flink.apache.org/)). Pulsar Functions are computing infrastructure of Pulsar messaging system. The core goal is tied to a series of other goals:
 
-* Developer productivity ([language-native](#language-native-functions) vs. [Pulsar Functions SDK](#the-pulsar-functions-sdk) functions)
+* Developer productivity ([language-native](#language-native-functions) vs [Pulsar Functions SDK](#the-pulsar-functions-sdk) functions)
 * Easy troubleshooting
 * Operational simplicity (no need for an external processing system)
 
 ## Inspirations
 
-The Pulsar Functions feature was inspired by (and takes cues from) several systems and paradigms:
+Pulsar Functions are inspired by (and take cues from) several systems and paradigms:
 
 * Stream processing engines such as [Apache Storm](http://storm.apache.org/), [Apache Heron](https://apache.github.io/incubator-heron), and [Apache Flink](https://flink.apache.org)
 * "Serverless" and "Function as a Service" (FaaS) cloud platforms like [Amazon Web Services Lambda](https://aws.amazon.com/lambda/), [Google Cloud Functions](https://cloud.google.com/functions/), and [Azure Cloud Functions](https://azure.microsoft.com/en-us/services/functions/)
 
-Pulsar Functions could be described as
+Pulsar Functions can be described as
 
 * [Lambda](https://aws.amazon.com/lambda/)-style functions that are
-* specifically designed to use Pulsar as a message bus
+* specifically designed to use Pulsar as a message bus.
 
 ## Programming model
 
-The core programming model behind Pulsar Functions is very simple:
+The core programming model of Pulsar Functions is simple. Functions receive messages from one or more **input [topics](reference-terminology.md#topic)**. Each time a message is received, the function will complete the following tasks.   
 
-* Functions receive messages from one or more **input [topics](reference-terminology.md#topic)**. Every time a message is received, the function can do a variety of things:
   * Apply some processing logic to the input and write output to:
     * An **output topic** in Pulsar
     * [Apache BookKeeper](#state-storage)
@@ -65,11 +83,11 @@ The core programming model behind Pulsar Functions is very simple:
 
 ### Word count example
 
-If you were to implement the classic word count example using Pulsar Functions, it might look something like this:
+If you implement the classic word count example using Pulsar Functions, it looks something like this:
 
 ![Pulsar Functions word count example](assets/pulsar-functions-word-count.png)
 
-If you were writing the function in [Java](functions-api.md#functions-for-java) using the [Pulsar Functions SDK for Java](functions-api.md#java-sdk-functions), you could write the function like below:
+To write the function in [Java](functions-api.md#functions-for-java) with [Pulsar Functions SDK for Java](functions-api.md#java-sdk-functions), you can write the function as follows.
 
 ```java
 package org.example.functions;
@@ -92,8 +110,8 @@ public class WordCountFunction implements Function<String, Void> {
 }
 ```
 
-Next, you need to bundle and build the jar file to be deployed, the approaches can be found in ["Creating an Uber JAR"](#creating-an-uber-jar) and ["Creating a NAR package"](#creating-a-nar-package).
-Then [deploy it](#cluster-run-mode) in your Pulsar cluster using the [command line](#command-line-interface) like below:
+Bundle and build the JAR file to be deployed. You can find approaches in [Creating an Uber JAR](#creating-an-uber-jar) and [Creating a NAR package](#creating-a-nar-package).
+Then [deploy it](#cluster-run-mode) in your Pulsar cluster using the [command line](#command-line-interface) as follows.
 
 ```bash
 $ bin/pulsar-admin functions create \
@@ -108,13 +126,13 @@ $ bin/pulsar-admin functions create \
 
 ### Content-based routing example
 
-The use cases for Pulsar Functions are essentially endless, but let's dig into a more sophisticated example that involves content-based routing.
+Pulsar Functions are used in many cases. The following is a sophisticated example that involves content-based routing.
 
-Imagine a function that takes items (strings) as input and publishes them to either a fruits or vegetables topic, depending on the item. Or, if an item is neither a fruit nor a vegetable, a warning is logged to a [log topic](#logging). Here's a visual representation:
+For example, a function takes items (strings) as input and publishes them to either a `fruits` or `vegetables` topic, depending on the item. Or, if an item is neither fruit nor vegetable, a warning is logged to a [log topic](#logging). The following is a visual representation.
 
 ![Pulsar Functions routing example](assets/pulsar-functions-routing-example.png)
 
-If you were implementing this routing functionality in Python, it might look something like this:
+If you implement this routing functionality in Python, it looks something like this:
 
 ```python
 from pulsar import Function
@@ -142,7 +160,7 @@ class RoutingFunction(Function):
 
 ## Command-line interface
 
-Pulsar Functions are managed using the [`pulsar-admin`](reference-pulsar-admin.md) CLI tool (in particular the [`functions`](reference-pulsar-admin.md#functions) command). Here's an example command that would run a function in [local run mode](#local-run-mode):
+Pulsar Functions are managed using the [`pulsar-admin`](reference-pulsar-admin.md) CLI tool (in particular the [`functions`](reference-pulsar-admin.md#functions) command). The following example runs a function in the [local run mode](#local-run-mode).
 
 ```bash
 $ bin/pulsar-admin functions localrun \
@@ -153,30 +171,28 @@ $ bin/pulsar-admin functions localrun \
 ```
 
 ## Fully Qualified Function Name (FQFN)
-
-Each Pulsar Function has a **Fully Qualified Function Name** (FQFN) that consists of three elements: the function's tenant, namespace, and function name. FQFN's look like this:
+Each Pulsar Function has a **Fully Qualified Function Name** (FQFN) that consists of three elements: the function tenant, namespace, and function name. FQFN looks like this:
 
 ```http
 tenant/namespace/name
 ```
 
-FQFNs enable you to, for example, create multiple functions with the same name provided that they're in different namespaces.
+FQFNs enable you to create multiple functions with the same name provided that they are in different namespaces.
 
 ## Configuration
-
-Pulsar Functions can be configured in two ways:
+You can configure a Pulsar Function in the following ways:
 
 * Via [command-line arguments](#command-line-interface) passed to the [`pulsar-admin functions`](reference-pulsar-admin.md#functions) interface
 * Via [YAML](http://yaml.org/) configuration files
 
-If you're supplying a YAML configuration, you must specify a path to the file on the command line. Here's an example:
+If you use a YAML configuration file, you must specify a path to the file on the command line. The following is an example.
 
 ```bash
 $ bin/pulsar-admin functions create \
   --function-config-file ./my-function.yaml
 ```
 
-And here's an example `my-function.yaml` file:
+The following is an example of the `my-function.yaml` file.
 
 ```yaml
 name: my-function
@@ -189,22 +205,20 @@ inputs:
 output: persistent://public/default/test_result
 ```
 
-You can also mix and match configuration methods by specifying some function attributes via the CLI and others via YAML configuration.
+You can specify some function attributes via CLI arguments or in a configuration file in YAML format.
 
 ## Supported languages
+Currently, you can write Pulsar Functions in [Java](functions-api.md#functions-for-java), [Python](functions-api.md#functions-for-python), and [Go](functions-api.md#functions-for-go). Support for additional languages is coming soon.
 
-Pulsar Functions can currently be written in [Java](functions-api.md#functions-for-java) and [Python](functions-api.md#functions-for-python). Support for additional languages is coming soon.
-
-## The Pulsar Functions API
+## Pulsar Functions API
 
-The Pulsar Functions API enables you to create processing logic that is:
+Pulsar Functions API enables you to create processing logic that is:
 
 * Type safe. Pulsar Functions can process raw bytes or more complex, application-specific types.
 * Based on SerDe (**Ser**ialization/**De**serialization). A variety of types are supported "out of the box" but you can also create your own custom SerDe logic.
 
 ### Function context
-
-Each Pulsar Function created using the [Pulsar Functions SDK](#the-pulsar-functions-sdk) has access to a context object that both provides:
+Each Pulsar Function created using [Pulsar Functions SDK](#the-pulsar-functions-sdk) has access to a context object that both provides:
 
 1. A wide variety of information about the function, including:
   * The name of the function
@@ -215,18 +229,15 @@ Each Pulsar Function created using the [Pulsar Functions SDK](#the-pulsar-functi
   * The ability to produce [metrics](#metrics)
 
 ### Language-native functions
+"Native" functions are supported in Java and Python, which means a Pulsar Function can have no dependencies.
 
-Both Java and Python support writing "native" functions, i.e. Pulsar Functions with no dependencies.
-
-The benefit of native functions is that they don't have any dependencies beyond what's already available in Java/Python "out of the box." The downside is that they don't provide access to the function's [context](#function-context), which is necessary for a variety of functionality, including [logging](#logging), [user configuration](#user-configuration), and more.
-
-## The Pulsar Functions SDK
+The benefit of native functions is that they do not have any dependencies beyond what's already available in Java/Python "out of the box." The downside is that they do not provide access to the function [context](#function-context), which is necessary for a variety of functionalities, including [logging](#logging), [user configuration](#user-configuration), and more.
 
-If you'd like a Pulsar Function to have access to a [context object](#function-context), you can use the **Pulsar Functions SDK**, available for both [Java](functions-api.md#functions-for-java) and [Python](functions-api.md#functions-for-python).
+## Pulsar Functions SDK   
+To enable a Pulsar Function to access to a [context object](#function-context), you can use **Pulsar Functions SDK**, available for [Java](functions-api.md#functions-for-java), [Python](functions-api.md#functions-for-python), and [Go](functions-api.md#functions-for-go).
 
 ### Java
-
-Here's an example Java function that uses information about its context:
+The following is a Java function example that uses information about its context.
 
 ```java
 import org.apache.pulsar.functions.api.Context;
@@ -247,8 +258,7 @@ public class ContextAwareFunction implements Function<String, Void> {
 ```
 
 ### Python
-
-Here's an example Python function that uses information about its context:
+The following is a Python function example that uses information about its context.
 
 ```python
 from pulsar import Function
@@ -262,18 +272,44 @@ class ContextAwareFunction(Function):
         log.info("Function tenant/namespace/name: {0}/{1}/{2}".format(function_tenant, function_namespace, function_name))
 ```
 
-## Deployment
+### Go
+The following is a Go function example that uses information about its context.
+
+```
+import (
+	"context"
+	"fmt"
+
+    "github.com/apache/pulsar/pulsar-function-go/log"
+	"github.com/apache/pulsar/pulsar-function-go/pf"
+)
+
+func contextFunc(ctx context.Context) {
+	if fc, ok := pf.FromContext(ctx); ok {
+		tenant := fc.GetFuncTenant()
+		namespace := fc.GetFuncNamespace()
+		name := fc.GetFuncName()
+		log.Info("Function tenant/namespace/name: %s/%s/%s\n", tenant, namespace, name)
+	}
+}
 
-The Pulsar Functions feature was built to support a variety of deployment options. At the moment, there are two ways to run Pulsar Functions:
+func main() {
+	pf.Start(contextFunc)
+}
+
+```
+
+## Deployment
+Pulsar Functions support a variety of deployment options. You can deploy a Pulsar Function in the following ways.
 
 Deployment mode | Description
 :---------------|:-----------
-[Local run mode](#local-run-mode) | The function runs in your local environment, for example on your laptop
-[Cluster mode](#cluster-run-mode) | The function runs *inside of* your Pulsar cluster, on the same machines as your Pulsar [brokers](reference-terminology.md#broker)
+[Local run mode](#local-run-mode) | The function runs in your local environment, for example, on your laptop.
+[Cluster mode](#cluster-run-mode) | The function runs *inside of* your Pulsar cluster, on the same machines as your Pulsar [brokers](reference-terminology.md#broker).
 
 ### Local run mode
 
-If you run a Pulsar Function in **local run** mode, it will run on the machine from which the command is run (this could be your laptop, an [AWS EC2](https://aws.amazon.com/ec2/) instance, etc.). Here's an example [`localrun`](reference-pulsar-admin.md#localrun) command:
+If you run a Pulsar Function in the **local run** mode, you run it on the machine where you run commands(for example, your laptop, an [AWS EC2](https://aws.amazon.com/ec2/) instance). The following example is about the [`localrun`](reference-pulsar-admin.md#localrun) command.
 
 ```bash
 $ bin/pulsar-admin functions localrun \
@@ -283,7 +319,7 @@ $ bin/pulsar-admin functions localrun \
   --output persistent://public/default/output-1
 ```
 
-By default, the function will connect to a Pulsar cluster running on the same machine, via a local broker service URL of `pulsar://localhost:6650`. If you'd like to use local run mode to run a function but connect it to a non-local Pulsar cluster, you can specify a different broker URL using the `--brokerServiceUrl` flag. Here's an example:
+By default, the function connects to a Pulsar cluster running on the same machine, via a local broker service URL of `pulsar://localhost:6650`. If you run a function with the local run mode, and connect it to a non-local Pulsar cluster, specify a different broker URL using the `--brokerServiceUrl` flag. The following is an example.
 
 ```bash
 $ bin/pulsar-admin functions localrun \
@@ -291,9 +327,8 @@ $ bin/pulsar-admin functions localrun \
   # Other function parameters
 ```
 
-### Cluster run mode
-
-When you run a Pulsar Function in **cluster mode**, the function code will be uploaded to a Pulsar broker and run *alongside the broker* rather than in your [local environment](#local-run-mode). You can run a function in cluster mode using the [`create`](reference-pulsar-admin.md#create-1) command. Here's an example:
+### Cluster mode
+When you run Pulsar Functions in the **cluster mode**, the function code is uploaded to a Pulsar broker and runs *alongside the broker* rather than in your [local environment](#local-run-mode). You can run a function in the cluster mode using the [`create`](reference-pulsar-admin.md#create-1) command.  The following is an example.
 
 ```bash
 $ bin/pulsar-admin functions create \
@@ -303,13 +338,13 @@ $ bin/pulsar-admin functions create \
   --output persistent://public/default/output-1
 ```
 
-This command will upload `myfunc.py` to Pulsar, which will use the code to start one [or more](#parallelism) instances of the function.
+This command uploads `myfunc.py` to Pulsar, which uses the code to start one [or more](#parallelism) instances of the function.
 
-### Parallelism
+### Run instances in parallel
 
-By default, only one **instance** of a Pulsar Function runs when you create and run it in [cluster run mode](#cluster-run-mode). You can also, however, run multiple instances in parallel. You can specify the number of instances when you create the function, or update an existing single-instance function with a new parallelism factor.
+When you create Pulsar Functions and run in the [cluster mode](#cluster-mode), only one **instance** of Pulsar Functions is running by default. However, you can run multiple instances in parallel. Specify the number of instances when you create Pulsar Functions, or update an existing single-instance function with a new parallel factor.
 
-This command, for example, would create and run a function with a parallelism of 5 (i.e. 5 instances):
+This command, for example, creates and runs a function with 5 instances in parallel.
 
 ```bash
 $ bin/pulsar-admin functions create \
@@ -323,7 +358,7 @@ $ bin/pulsar-admin functions create \
 
 ### Function instance resources
 
-When you run Pulsar Functions in [cluster run](#cluster-run-mode) mode, you can specify the resources that are assigned to each function [instance](#parallelism):
+When you run Pulsar Functions in the [cluster mode](#cluster-mode), you can specify the resources that are assigned to each function [instance](#run-instances-in-parallel).
 
 Resource | Specified as... | Runtimes
 :--------|:----------------|:--------
@@ -331,7 +366,7 @@ CPU | The number of cores | Docker (coming soon)
 RAM | The number of bytes | Process, Docker
 Disk space | The number of bytes | Docker
 
-Here's an example function creation command that allocates 8 cores, 8 GB of RAM, and 10 GB of disk space to a function:
+The following example allocates 8 cores, 8 GB of RAM, and 10 GB of disk space to a function.
 
 ```bash
 $ bin/pulsar-admin functions create \
@@ -346,7 +381,7 @@ For more information on resources, see the [Deploying and Managing Pulsar Functi
 
 ### Logging
 
-Pulsar Functions created using the [Pulsar Functions SDK](#the-pulsar-functions-sdk) can send logs to a log topic that you specify as part of the function's configuration. The function created using the command below, for example, would produce all logs on the `persistent://public/default/my-func-1-log` topic:
+Pulsar Functions created using [Pulsar Functions SDK](#the-pulsar-functions-sdk) can send logs to a log topic that you specify as part of the function configuration. The function created using the following command produces all logs on the `persistent://public/default/my-func-1-log` topic.
 
 ```bash
 $ bin/pulsar-admin functions create \
@@ -355,7 +390,7 @@ $ bin/pulsar-admin functions create \
   # Other configs
 ```
 
-Here's an example [Java function](functions-api.md#java-logging) that logs at different log levels based on the function's input:
+The following is an example of [Java function](functions-api.md#java-logging) that logs at different log levels based on the function input.
 
 ```java
 public class LoggerFunction implements Function<String, Void> {
@@ -371,11 +406,36 @@ public class LoggerFunction implements Function<String, Void> {
 }
 ```
 
+The following is an example of [Go function](functions-api.md#go-logging) that logs at different log levels based on the function input.
+
+```
+import (
+	"context"
+
+	"github.com/apache/pulsar/pulsar-function-go/log"
+	"github.com/apache/pulsar/pulsar-function-go/pf"
+)
+
+func loggerFunc(ctx context.Context, input []byte) {
+	if len(input) <= 100 {
+		log.Infof("This input has a length of: %d", len(input))
+	} else {
+		log.Warnf("This input is getting too long! It has {%d} characters", len(input))
+	}
+}
+
+func main() {
+	pf.Start(loggerFunc)
+}
+```
+
+When you use `logTopic` related functionalities in Go Function, import `github.com/apache/pulsar/pulsar-function-go/log`, and you do not have to use the `getLogger()` context object. The approach is different from Java Function and Python Function.
+
 ### User configuration
 
-Pulsar Functions can be passed arbitrary key-values via the command line (both keys and values must be strings). This set of key-values is called the functions **user configuration**. User configurations must consist of JSON strings.
+You can pass arbitrary key-values to Pulsar Functions via the command line (both keys and values must be string). This set of key-values is called the functions **user configuration**. User configuration must consist of JSON strings.
 
-Here's an example of passing a user configuration to a function:
+The following example passes user configuration to a function.
 
 ```bash
 $ bin/pulsar-admin functions create \
@@ -383,7 +443,7 @@ $ bin/pulsar-admin functions create \
   # Other configs
 ```
 
-Here's an example of a function that accesses that config map:
+The following example accesses that configuration map.
 
 ```java
 public class ConfigMapFunction implements Function<String, Void> {
@@ -397,20 +457,21 @@ public class ConfigMapFunction implements Function<String, Void> {
 }
 ```
 
-### Triggering Pulsar Functions
+### Trigger Pulsar Functions
 
-Pulsar Functions running in [cluster mode](#cluster-run-mode) can be [triggered](functions-deploying.md#triggering-pulsar-functions) via the [command line](#command-line-interface). With triggering you can easily pass a specific value to a function and get the function's return value *without* needing to worry about creating a client, sending a message to the right input topic, etc. Triggering can be very useful for---but is by no means limited to---testing and debugging purposes.
+You can [trigger](functions-deploying.md#triggering-pulsar-functions) a Pulsar Function running in the [cluster mode](#cluster-mode) with the [command line](#command-line-interface). When triggering a Pulsar Function, you can pass a specific value to the Function and get the return value *without* creating a client. Triggering is useful for, but not limited to, testing and debugging purposes.
 
-> Triggering a function is ultimately no different from invoking a function by producing a message on one of the function's input topics. The [`pulsar-admin functions trigger`](reference-pulsar-admin.md#trigger) command is essentially a convenient mechanism for sending messages to functions without needing to use the [`pulsar-client`](reference-cli-tools.md#pulsar-client) tool or a language-specific client library.
+> Note   
+> Triggering a function is no different from invoking a function by producing a message on one of the function input topics. The [`pulsar-admin functions trigger`](reference-pulsar-admin.md#trigger) command is a convenient mechanism for sending messages to functions without using the [`pulsar-client`](reference-cli-tools.md#pulsar-client) tool or a language-specific client library.
 
-Let's take an example Pulsar Function written in Python (using the [native interface](functions-api.md#python-native-functions)) that simply reverses string inputs:
+The following is an example of Pulsar Functions written in Python (using the [native interface](functions-api.md#python-native-functions)) that simply reverses string inputs.
 
 ```python
 def process(input):
     return input[::-1]
 ```
 
-If that function were running in a Pulsar cluster, it could be triggered like this:
+If the function is running in a Pulsar cluster, you can trigger it with the following commands.
 
 ```bash
 $ bin/pulsar-admin functions trigger \
@@ -420,21 +481,22 @@ $ bin/pulsar-admin functions trigger \
   --trigger-value "snoitcnuf raslup ot emoclew"
 ```
 
-That should return `welcome to pulsar functions` as the console output.
+And then `welcome to Pulsar Functions` is displayed in the console output.
 
-> Instead of passing in a string via the CLI, you can also trigger a Pulsar Function with the contents of a file using the `--triggerFile` flag.
+> Note   
+> Instead of passing a string via the CLI, you can trigger Pulsar Functions with the contents of a file using the `--triggerFile` flag.
 
 ## Processing guarantees
 
-The Pulsar Functions feature provides three different messaging semantics that you can apply to any function:
+Pulsar Functions provide three different messaging semantics that you can apply to any function.
 
 Delivery semantics | Description
 :------------------|:-------
-**At-most-once** delivery | Each message that is sent to the function will most likely be processed but also may not be (hence the "at most")
-**At-least-once** delivery | Each message that is sent to the function could be processed more than once (hence the "at least")
-**Effectively-once** delivery | Each message that is sent to the function will have one output associated with it
+**At-most-once** delivery | Each message sent to the function is likely to be processed, or not to be processed (hence "at most").
+**At-least-once** delivery | Each message sent to the function can be processed more than once (hence the "at least").
+**Effectively-once** delivery | Each message sent to the function will have one output associated with it.
 
-This command, for example, would run a function in [cluster mode](#cluster-run-mode) with effectively-once guarantees applied:
+This command, for example, runs a function in the [cluster mode](#cluster-mode) with effectively-once guarantees applied.
 
 ```bash
 $ bin/pulsar-admin functions create \
@@ -444,9 +506,7 @@ $ bin/pulsar-admin functions create \
 ```
 
 ## Metrics
-
-Pulsar Functions that use the [Pulsar Functions SDK](#the-pulsar-functions-sdk) can publish metrics to Pulsar. For more information, see [Metrics for Pulsar Functions](functions-metrics.md).
+Pulsar Functions that use [Pulsar Functions SDK](#the-pulsar-functions-sdk) can publish metrics to Pulsar. For more information, see [Metrics for Pulsar Functions](functions-metrics.md).
 
 ## State storage
-
-Pulsar Functions use [Apache BookKeeper](https://bookkeeper.apache.org) as a state storage interface. All Pulsar installations, including local standalone installations, include a deployment of BookKeeper bookies.
+Pulsar Functions use [Apache BookKeeper](https://bookkeeper.apache.org) as a state storage interface. Pulsar installation, including the local standalone installation, includes deployment of BookKeeper bookies.
\ No newline at end of file