functions_framework 0.3.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +33 -1
- data/README.md +8 -8
- data/docs/deploying-functions.md +7 -1
- data/docs/overview.md +3 -3
- data/docs/testing-functions.md +9 -11
- data/docs/writing-functions.md +33 -19
- data/lib/functions_framework.rb +10 -17
- data/lib/functions_framework/function.rb +81 -24
- data/lib/functions_framework/legacy_event_converter.rb +29 -30
- data/lib/functions_framework/registry.rb +2 -16
- data/lib/functions_framework/server.rb +20 -14
- data/lib/functions_framework/testing.rb +60 -22
- data/lib/functions_framework/version.rb +1 -1
- metadata +17 -104
- data/lib/functions_framework/cloud_events.rb +0 -43
- data/lib/functions_framework/cloud_events/content_type.rb +0 -139
- data/lib/functions_framework/cloud_events/errors.rb +0 -42
- data/lib/functions_framework/cloud_events/event.rb +0 -79
- data/lib/functions_framework/cloud_events/event/v1.rb +0 -363
- data/lib/functions_framework/cloud_events/http_binding.rb +0 -270
- data/lib/functions_framework/cloud_events/json_format.rb +0 -122
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 780a948604e7295463a6fa73d771a212c0df6f1b49b9e04d75568c499b201c04
|
4
|
+
data.tar.gz: 1e5e02ca296f24a0e86e95b9aaff9b680e687c67cda90199ee6854367752fb63
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f92218000f31d2a60494a2ac2273f20af3bd584da1fa524964e45460a6670686e77eee0bc807e1d9add0d779e842c05ed054d7e89b16cae0a8496557dbd76269
|
7
|
+
data.tar.gz: 93e7e1a801cf4a4c6a32e051d6c39d8e5a70bbfe18aca97838d690faf0e22995c3595b1ea3075a356d4d6a1af267edfff10f424727aa4da1c4cf246b48ec3528
|
data/CHANGELOG.md
CHANGED
@@ -1,12 +1,44 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
### v0.5.1 / 2020-07-20
|
4
|
+
|
5
|
+
* Updated some documentation links. No functional changes.
|
6
|
+
|
7
|
+
### v0.5.0 / 2020-07-09
|
8
|
+
|
9
|
+
* Removed embedded CloudEvents classes and added the official CloudEvents SDK as a dependency. A `FunctionsFramework::CloudEvents` alias provides backward compatibility.
|
10
|
+
|
11
|
+
### v0.4.1 / 2020-07-08
|
12
|
+
|
13
|
+
* Fixed unsupported signal error on Windows.
|
14
|
+
* Fixed several edge case errors in legacy event conversion.
|
15
|
+
* Generated Content-Type headers now properly quote param values if needed.
|
16
|
+
* Minor documentation updates.
|
17
|
+
|
18
|
+
### v0.4.0 / 2020-06-29
|
19
|
+
|
20
|
+
* Dropped the legacy and largely unsupported `:event` function type. All event functions should be of type `:cloud_event`.
|
21
|
+
* Define the object context for function execution, and include an extensible context helper.
|
22
|
+
* Support for CloudEvents with specversion 0.3.
|
23
|
+
* CloudEvents now correct percent-encodes/decodes binary headers.
|
24
|
+
* CloudEvents now includes more robust RFC 2045 parsing of the Content-Type header.
|
25
|
+
* The CloudEventsError class now properly subclasses StandardError instead of RuntimeError.
|
26
|
+
* Removed redundant `_string` accessors from event classes since raw forms are already available via `[]`.
|
27
|
+
* A variety of corrections to event-related class documentation.
|
28
|
+
|
29
|
+
### v0.3.1 / 2020-06-27
|
30
|
+
|
31
|
+
* Fixed crash when using "return" directly in a function block.
|
32
|
+
* Added a more flexible request generation helper in the testing module.
|
33
|
+
* Fixed several typos in the documentation.
|
34
|
+
|
3
35
|
### v0.3.0 / 2020-06-26
|
4
36
|
|
5
37
|
* Updated the CloudEvent data format for converted pubsub events to conform to Cloud Run's conversion.
|
6
38
|
|
7
39
|
### v0.2.1 / 2020-06-25
|
8
40
|
|
9
|
-
* The `--signature-type` check recognizes the legacy `event` type.
|
41
|
+
* The `--signature-type` check recognizes the legacy `event` type for `:cloud_event` functions.
|
10
42
|
|
11
43
|
### v0.2.0 / 2020-06-24
|
12
44
|
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Functions Framework [](https://
|
1
|
+
# Functions Framework [](https://googlecloudplatform.github.io/functions-framework-ruby/latest) [](https://badge.fury.io/rb/functions_framework)
|
2
2
|
|
3
3
|
An open source framework for writing lightweight, portable Ruby functions that
|
4
4
|
run in a serverless environment. Functions written to this Framework will run
|
@@ -60,7 +60,7 @@ Create a `Gemfile` listing the Functions Framework as a dependency:
|
|
60
60
|
```ruby
|
61
61
|
# Gemfile
|
62
62
|
source "https://rubygems.org"
|
63
|
-
gem "functions_framework", "~> 0.
|
63
|
+
gem "functions_framework", "~> 0.5"
|
64
64
|
```
|
65
65
|
|
66
66
|
Create a file called `app.rb` and include the following code. This defines a
|
@@ -88,7 +88,7 @@ bundle exec functions-framework-ruby --target hello
|
|
88
88
|
In a separate shell, you can send requests to this function using curl:
|
89
89
|
|
90
90
|
```sh
|
91
|
-
curl
|
91
|
+
curl http://localhost:8080
|
92
92
|
# Output: Hello, world!
|
93
93
|
```
|
94
94
|
|
@@ -98,26 +98,26 @@ Stop the server with `CTRL+C`.
|
|
98
98
|
|
99
99
|
These guides provide additional getting-started information.
|
100
100
|
|
101
|
-
* **[Writing Functions](https://
|
101
|
+
* **[Writing Functions](https://googlecloudplatform.github.io/functions-framework-ruby/latest/file.writing-functions.html)**
|
102
102
|
: How to write functions that respond to HTTP requests, industry-standard
|
103
103
|
[CloudEvents](https://cloudevents.io), as well as events sent from Google
|
104
104
|
Cloud services such as [Pub/Sub](https://cloud.google.com/pubsub) and
|
105
105
|
[Storage](https://cloud.google.com/storage).
|
106
|
-
* **[Testing Functions](https://
|
106
|
+
* **[Testing Functions](https://googlecloudplatform.github.io/functions-framework-ruby/latest/file.testing-functions.html)**
|
107
107
|
: How to use the testing features of the Functions Framework to write local
|
108
108
|
unit tests for your functions using standard Ruby testing frameworks such
|
109
109
|
as [Minitest](https://github.com/seattlerb/minitest) and
|
110
110
|
[RSpec](https://rspec.info/).
|
111
|
-
* **[Running a Functions Server](https://
|
111
|
+
* **[Running a Functions Server](https://googlecloudplatform.github.io/functions-framework-ruby/latest/file.running-a-functions-server.html)**
|
112
112
|
: How to use the `functions-framework-ruby` executable to run a local
|
113
113
|
functions server.
|
114
|
-
* **[Deploying Functions](https://
|
114
|
+
* **[Deploying Functions](https://googlecloudplatform.github.io/functions-framework-ruby/latest/file.deploying-functions.html)**
|
115
115
|
: How to deploy functions to
|
116
116
|
[Google Cloud Functions](https://cloud.google.com/functions) or
|
117
117
|
[Google Cloud Run](https://cloud.google.com/run).
|
118
118
|
|
119
119
|
The library reference documentation can be found at:
|
120
|
-
https://
|
120
|
+
https://googlecloudplatform.github.io/functions-framework-ruby
|
121
121
|
|
122
122
|
Additional examples are available in the `examples` directory:
|
123
123
|
https://github.com/GoogleCloudPlatform/functions-framework-ruby/blob/master/examples/
|
data/docs/deploying-functions.md
CHANGED
@@ -105,6 +105,12 @@ to adapt it if you have an Anthos installation.
|
|
105
105
|
|
106
106
|
### Building an image for your function
|
107
107
|
|
108
|
+
Before you can deploy to Cloud Run, make sure your bundle, and in
|
109
|
+
particular your `Gemfile.lock` file, is up to date. The easiest way to do this
|
110
|
+
is to `bundle install` or `bundle update` and run your local tests prior to
|
111
|
+
deploying. The configuration used in the Dockerfile below will not accept your
|
112
|
+
function unless an up-to-date `Gemfile.lock` is present.
|
113
|
+
|
108
114
|
First, build a Docker image containing your function. Following is a simple
|
109
115
|
Dockerfile that you can use as a starting point. Feel free to adjust it to the
|
110
116
|
needs of your project:
|
@@ -165,7 +171,7 @@ deployed function.
|
|
165
171
|
|
166
172
|
Note that our Dockerfile's entrypoint did not pass any source file or target
|
167
173
|
name to the Functions Framework. If these are not specified, the Framework will
|
168
|
-
use the source
|
174
|
+
use the source `./app.rb` and the target `function` by default. To use different
|
169
175
|
values, you need to set the appropriate environment variables when deploying, as
|
170
176
|
illustrated above with the `FUNCTION_SOURCE` and `FUNCTION_TARGET` variables.
|
171
177
|
|
data/docs/overview.md
CHANGED
@@ -64,7 +64,7 @@ Create a `Gemfile` listing the Functions Framework as a dependency:
|
|
64
64
|
```ruby
|
65
65
|
# Gemfile
|
66
66
|
source "https://rubygems.org"
|
67
|
-
gem "functions_framework", "~> 0.
|
67
|
+
gem "functions_framework", "~> 0.5"
|
68
68
|
```
|
69
69
|
|
70
70
|
Create a file called `app.rb` and include the following code. This defines a
|
@@ -92,7 +92,7 @@ bundle exec functions-framework-ruby --target hello
|
|
92
92
|
In a separate shell, you can send requests to this function using curl:
|
93
93
|
|
94
94
|
```sh
|
95
|
-
curl
|
95
|
+
curl http://localhost:8080
|
96
96
|
# Output: Hello, world!
|
97
97
|
```
|
98
98
|
|
@@ -121,7 +121,7 @@ These guides provide additional getting-started information.
|
|
121
121
|
[Google Cloud Run](https://cloud.google.com/run).
|
122
122
|
|
123
123
|
The library reference documentation can be found at:
|
124
|
-
https://
|
124
|
+
https://googlecloudplatform.github.io/functions-framework-ruby
|
125
125
|
|
126
126
|
Additional examples are available in the GitHub repository:
|
127
127
|
https://github.com/GoogleCloudPlatform/functions-framework-ruby/blob/master/examples/
|
data/docs/testing-functions.md
CHANGED
@@ -17,9 +17,8 @@ the output. You do not need to set up (or mock) an actual server.
|
|
17
17
|
The Functions Framework provides utility methods that streamline the process of
|
18
18
|
setting up functions and the environment for testing, constructing input
|
19
19
|
parameters, and interpreting results. These are available in the
|
20
|
-
|
21
|
-
|
22
|
-
describe block.
|
20
|
+
{FunctionsFramework::Testing} module. Generally, you can include this module in
|
21
|
+
your Minitest test class or RSpec describe block.
|
23
22
|
|
24
23
|
```ruby
|
25
24
|
require "minitest/autorun"
|
@@ -45,10 +44,10 @@ end
|
|
45
44
|
|
46
45
|
To test a function, you'll need to load the Ruby file that defines the function,
|
47
46
|
and run the function to test its results. The Testing module provides a method
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
47
|
+
{FunctionsFramework::Testing#load_temporary}, which loads a Ruby file, defining
|
48
|
+
functions but only for the scope of your test. This allows your test to coexist
|
49
|
+
with tests for other functions, even functions with the same name from a
|
50
|
+
different Ruby file.
|
52
51
|
|
53
52
|
```ruby
|
54
53
|
require "minitest/autorun"
|
@@ -91,8 +90,8 @@ includes helper methods that you can use to create simple requests for many
|
|
91
90
|
basic cases.
|
92
91
|
|
93
92
|
When you have constructed an input request, use
|
94
|
-
|
95
|
-
|
93
|
+
{FunctionsFramework::Testing#call_http} to call a named function, passing the
|
94
|
+
request object. This method returns a
|
96
95
|
[Rack::Response](https://rubydoc.info/gems/rack/Rack/Response) that you can
|
97
96
|
assert against.
|
98
97
|
|
@@ -142,8 +141,7 @@ end
|
|
142
141
|
|
143
142
|
Testing a CloudEvent function works similarly. The `Testing` module provides
|
144
143
|
methods to help construct example CloudEvent objects, which can then be passed
|
145
|
-
to the method
|
146
|
-
[call_event](https://rubydoc.info/gems/functions_framework/FunctionsFramework/Testing#call_event-instance_method).
|
144
|
+
to the method {FunctionsFramework::Testing#call_event}.
|
147
145
|
|
148
146
|
Unlike HTTP functions, event functions do not have a return value. Instead, you
|
149
147
|
will need to test side effects. A common approach is to test logs by capturing
|
data/docs/writing-functions.md
CHANGED
@@ -30,7 +30,7 @@ that returns a simple message in the HTTP response body:
|
|
30
30
|
```ruby
|
31
31
|
require "functions_framework"
|
32
32
|
|
33
|
-
FunctionsFramework.http
|
33
|
+
FunctionsFramework.http "hello" do |request|
|
34
34
|
# Return the response body.
|
35
35
|
"Hello, world!\n"
|
36
36
|
end
|
@@ -43,7 +43,7 @@ now cover these in a bit more detail.
|
|
43
43
|
|
44
44
|
An HTTP function is passed a request, which is an object of type
|
45
45
|
[Rack::Request](https://rubydoc.info/gems/rack/Rack/Request). This object
|
46
|
-
provides methods
|
46
|
+
provides methods for obtaining request information such as the method,
|
47
47
|
path, query parameters, body content, and headers. You can also obtain the raw
|
48
48
|
Rack environment using the `env` method. The following example includes some
|
49
49
|
request information in the response:
|
@@ -51,7 +51,7 @@ request information in the response:
|
|
51
51
|
```ruby
|
52
52
|
require "functions_framework"
|
53
53
|
|
54
|
-
FunctionsFramework.http
|
54
|
+
FunctionsFramework.http "request_info_example" do |request|
|
55
55
|
# Include some request info in the response body.
|
56
56
|
"Received #{request.method} from #{request.url}!\n"
|
57
57
|
end
|
@@ -66,7 +66,7 @@ hosting environment.
|
|
66
66
|
```ruby
|
67
67
|
require "functions_framework"
|
68
68
|
|
69
|
-
FunctionsFramework.http
|
69
|
+
FunctionsFramework.http "logging_example" do |request|
|
70
70
|
# Log some request info.
|
71
71
|
request.logger.info "I received #{request.method} from #{request.url}!"
|
72
72
|
# A simple response body.
|
@@ -106,10 +106,19 @@ framework such as Ruby on Rails, you may want to consider a solution such as
|
|
106
106
|
Google Cloud Run that is tailored to larger applications. However, a lightweight
|
107
107
|
framework such as Sinatra is sometimes useful when writing HTTP functions.
|
108
108
|
|
109
|
-
It is easy to connect an HTTP function to a Sinatra app.
|
110
|
-
|
111
|
-
|
112
|
-
|
109
|
+
It is easy to connect an HTTP function to a Sinatra app. First, declare the
|
110
|
+
dependency on Sinatra in your `Gemfile`:
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
# Gemfile
|
114
|
+
source "https://rubygems.org"
|
115
|
+
gem "functions_framework", "~> 0.5"
|
116
|
+
gem "sinatra", "~> 2.0"
|
117
|
+
```
|
118
|
+
|
119
|
+
Write the Sinatra app using the "modular" Sinatra interface (i.e. subclass
|
120
|
+
`Sinatra::Base`), and then run the Sinatra app directly as a Rack handler from
|
121
|
+
the function. Here is a basic example:
|
113
122
|
|
114
123
|
```ruby
|
115
124
|
require "functions_framework"
|
@@ -143,20 +152,25 @@ information about it:
|
|
143
152
|
```ruby
|
144
153
|
require "functions_framework"
|
145
154
|
|
146
|
-
FunctionsFramework.cloud_event
|
155
|
+
FunctionsFramework.cloud_event "hello" do |event|
|
147
156
|
FunctionsFramework.logger.info "I received an event of type #{event.type}!"
|
148
157
|
end
|
149
158
|
```
|
150
159
|
|
151
|
-
The event parameter
|
152
|
-
[CloudEvents
|
153
|
-
object
|
154
|
-
|
160
|
+
The event parameter will be either a
|
161
|
+
[CloudEvents V0.3 Event](https://cloudevents.github.io/sdk-ruby/latest/CloudEvents/Event/V0)
|
162
|
+
object ([see spec](https://github.com/cloudevents/spec/blob/v0.3/spec.md)) or a
|
163
|
+
[CloudEvents V1.0 Event](https://cloudevents.github.io/sdk-ruby/latest/CloudEvents/Event/V1)
|
164
|
+
object ([see spec](https://github.com/cloudevents/spec/blob/v1.0/spec.md)).
|
155
165
|
|
156
166
|
Some Google Cloud services send events in a legacy event format that was defined
|
157
167
|
prior to CloudEvents. The Functions Framework will convert these legacy events
|
158
|
-
to an equivalent CloudEvents type, so your function will always receive a
|
159
|
-
CloudEvent object when it is sent an event from Google Cloud.
|
168
|
+
to an equivalent CloudEvents V1 type, so your function will always receive a
|
169
|
+
CloudEvent object when it is sent an event from Google Cloud. The precise
|
170
|
+
mapping between legacy events and CloudEvents is not specified in detail here,
|
171
|
+
but in general, the _data_ from the legacy event will be mapped to the `data`
|
172
|
+
field in the CloudEvent, and the _context_ from the legacy event will be mapped
|
173
|
+
to equivalent CloudEvent attributes.
|
160
174
|
|
161
175
|
## Error handling
|
162
176
|
|
@@ -175,7 +189,7 @@ HTTP response yourself. For example:
|
|
175
189
|
```ruby
|
176
190
|
require "functions_framework"
|
177
191
|
|
178
|
-
FunctionsFramework.http
|
192
|
+
FunctionsFramework.http "error_reporter" do |request|
|
179
193
|
begin
|
180
194
|
raise "whoops!"
|
181
195
|
rescue RuntimeError => e
|
@@ -222,7 +236,7 @@ A simple project might look like this:
|
|
222
236
|
```ruby
|
223
237
|
# Gemfile
|
224
238
|
source "https://rubygems.org"
|
225
|
-
gem "functions_framework", "~> 0.
|
239
|
+
gem "functions_framework", "~> 0.5"
|
226
240
|
```
|
227
241
|
|
228
242
|
```ruby
|
@@ -230,7 +244,7 @@ gem "functions_framework", "~> 0.3"
|
|
230
244
|
require "functions_framework"
|
231
245
|
require_relative "lib/hello"
|
232
246
|
|
233
|
-
FunctionsFramework.http
|
247
|
+
FunctionsFramework.http "hello" do |request|
|
234
248
|
Hello.new(request).build_response
|
235
249
|
end
|
236
250
|
```
|
@@ -238,7 +252,7 @@ end
|
|
238
252
|
```ruby
|
239
253
|
# lib/hello.rb
|
240
254
|
class Hello
|
241
|
-
def initialize
|
255
|
+
def initialize request
|
242
256
|
@request = request
|
243
257
|
end
|
244
258
|
|
data/lib/functions_framework.rb
CHANGED
@@ -14,7 +14,8 @@
|
|
14
14
|
|
15
15
|
require "logger"
|
16
16
|
|
17
|
-
require "
|
17
|
+
require "cloud_events"
|
18
|
+
|
18
19
|
require "functions_framework/function"
|
19
20
|
require "functions_framework/legacy_event_converter"
|
20
21
|
require "functions_framework/registry"
|
@@ -44,10 +45,6 @@ require "functions_framework/version"
|
|
44
45
|
#
|
45
46
|
# Here is a roadmap to the internal modules in the Ruby functions framework.
|
46
47
|
#
|
47
|
-
# * {FunctionsFramework::CloudEvents} provides an implementation of the
|
48
|
-
# [CloudEvents](https://cloudevents.io) specification. In particular, if
|
49
|
-
# you define an event function, you will receive the event as a
|
50
|
-
# {FunctionsFramework::CloudEvents::Event} object.
|
51
48
|
# * {FunctionsFramework::CLI} is the implementation of the
|
52
49
|
# `functions-framework-ruby` executable. Most apps will not need to interact
|
53
50
|
# with this class directly.
|
@@ -94,6 +91,12 @@ module FunctionsFramework
|
|
94
91
|
#
|
95
92
|
DEFAULT_SOURCE = "./app.rb".freeze
|
96
93
|
|
94
|
+
##
|
95
|
+
# The CloudEvents implementation was extracted to become the official
|
96
|
+
# CloudEvents SDK. This alias is left here for backward compatibility.
|
97
|
+
#
|
98
|
+
CloudEvents = ::CloudEvents
|
99
|
+
|
97
100
|
class << self
|
98
101
|
##
|
99
102
|
# The "global" registry that holds events defined by the
|
@@ -139,23 +142,13 @@ module FunctionsFramework
|
|
139
142
|
self
|
140
143
|
end
|
141
144
|
|
142
|
-
##
|
143
|
-
# This is an obsolete interface that defines an event function taking two
|
144
|
-
# arguments (data and context) rather than one.
|
145
|
-
#
|
146
|
-
# @deprecated Use {FunctionsFramework.cloud_event} instead.
|
147
|
-
#
|
148
|
-
def event name = DEFAULT_TARGET, &block
|
149
|
-
global_registry.add_event name, &block
|
150
|
-
self
|
151
|
-
end
|
152
|
-
|
153
145
|
##
|
154
146
|
# Define a function that responds to CloudEvents.
|
155
147
|
#
|
156
148
|
# You must provide a name for the function, and a block that implemets the
|
157
149
|
# function. The block should take one argument: the event object of type
|
158
|
-
#
|
150
|
+
# [`CloudEvents::Event`](https://cloudevents.github.io/sdk-ruby/latest/CloudEvents/Event).
|
151
|
+
# Any return value is ignored.
|
159
152
|
#
|
160
153
|
# ## Example
|
161
154
|
#
|
@@ -16,21 +16,60 @@ module FunctionsFramework
|
|
16
16
|
##
|
17
17
|
# Representation of a function.
|
18
18
|
#
|
19
|
-
# A function has a name, a type, and
|
19
|
+
# A function has a name, a type, and an implementation.
|
20
|
+
#
|
21
|
+
# The implementation in general is an object that responds to the `call`
|
22
|
+
# method. For a function of type `:http`, the `call` method takes a single
|
23
|
+
# `Rack::Request` argument and returns one of various HTTP response types.
|
24
|
+
# See {FunctionsFramework::Registry.add_http}. For a function of type
|
25
|
+
# `:cloud_event`, the `call` method takes a single
|
26
|
+
# [CloudEvent](https://cloudevents.github.io/sdk-ruby/latest/CloudEvents/Event)
|
27
|
+
# argument, and does not return a value.
|
28
|
+
# See {FunctionsFramework::Registry.add_cloud_event}.
|
29
|
+
#
|
30
|
+
# If a callable object is provided directly, its `call` method is invoked for
|
31
|
+
# every function execution. Note that this means it may be called multiple
|
32
|
+
# times concurrently in separate threads.
|
33
|
+
#
|
34
|
+
# Alternately, the implementation may be provided as a class that should be
|
35
|
+
# instantiated to produce a callable object. If a class is provided, it should
|
36
|
+
# either subclass {FunctionsFramework::Function::CallBase} or respond to the
|
37
|
+
# same constructor interface, i.e. accepting arbitrary keyword arguments. A
|
38
|
+
# separate callable object will be instantiated from this class for every
|
39
|
+
# function invocation, so each instance will be used for only one invocation.
|
40
|
+
#
|
41
|
+
# Finally, an implementation can be provided as a block. If a block is
|
42
|
+
# provided, it will be recast as a `call` method in an anonymous subclass of
|
43
|
+
# {FunctionsFramework::Function::CallBase}. Thus, providing a block is really
|
44
|
+
# just syntactic sugar for providing a class. (This means, for example, that
|
45
|
+
# the `return` keyword will work within the block because it is treated as a
|
46
|
+
# method.)
|
20
47
|
#
|
21
48
|
class Function
|
22
49
|
##
|
23
50
|
# Create a new function definition.
|
24
51
|
#
|
25
52
|
# @param name [String] The function name
|
26
|
-
# @param type [Symbol] The type of function. Valid types are
|
27
|
-
# `:
|
28
|
-
# @param
|
53
|
+
# @param type [Symbol] The type of function. Valid types are `:http` and
|
54
|
+
# `:cloud_event`.
|
55
|
+
# @param callable [Class,#call] A callable object or class.
|
56
|
+
# @param block [Proc] The function code as a block.
|
29
57
|
#
|
30
|
-
def initialize name, type, &block
|
58
|
+
def initialize name, type, callable = nil, &block
|
31
59
|
@name = name
|
32
60
|
@type = type
|
33
|
-
@
|
61
|
+
@callable = @callable_class = nil
|
62
|
+
if callable.respond_to? :call
|
63
|
+
@callable = callable
|
64
|
+
elsif callable.is_a? ::Class
|
65
|
+
@callable_class = callable
|
66
|
+
elsif block_given?
|
67
|
+
@callable_class = ::Class.new CallBase do
|
68
|
+
define_method :call, &block
|
69
|
+
end
|
70
|
+
else
|
71
|
+
raise ::ArgumentError, "No callable given for function"
|
72
|
+
end
|
34
73
|
end
|
35
74
|
|
36
75
|
##
|
@@ -44,30 +83,48 @@ module FunctionsFramework
|
|
44
83
|
attr_reader :type
|
45
84
|
|
46
85
|
##
|
47
|
-
#
|
86
|
+
# Get a callable for performing a function invocation. This will either
|
87
|
+
# return the singleton callable object, or instantiate a new callable from
|
88
|
+
# the configured class.
|
48
89
|
#
|
49
|
-
|
90
|
+
# @param logger [::Logger] The logger for use by function executions. This
|
91
|
+
# may or may not be used by the callable.
|
92
|
+
# @return [#call]
|
93
|
+
#
|
94
|
+
def new_call logger: nil
|
95
|
+
return @callable unless @callable.nil?
|
96
|
+
logger ||= FunctionsFramework.logger
|
97
|
+
@callable_class.new logger: logger, function_name: name, function_type: type
|
98
|
+
end
|
50
99
|
|
51
100
|
##
|
52
|
-
#
|
53
|
-
# of function.
|
54
|
-
#
|
55
|
-
# * A `:http` type function takes a `Rack::Request` argument, and returns
|
56
|
-
# a Rack response type. See {FunctionsFramework::Registry.add_http}.
|
57
|
-
# * A `:cloud_event` type function takes a
|
58
|
-
# {FunctionsFramework::CloudEvents::Event} argument, and does not
|
59
|
-
# return a value. See {FunctionsFramework::Registry.add_cloud_event}.
|
101
|
+
# A base class for a callable object that provides calling context.
|
60
102
|
#
|
61
|
-
#
|
62
|
-
# @return [Object]
|
103
|
+
# An object of this class is `self` while a function block is running.
|
63
104
|
#
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
105
|
+
class CallBase
|
106
|
+
##
|
107
|
+
# Create a callable object with the given context.
|
108
|
+
#
|
109
|
+
# @param context [keywords] A set of context arguments. See {#context} for
|
110
|
+
# a list of keys that will generally be passed in. However,
|
111
|
+
# implementations should be prepared to accept any abritrary keys.
|
112
|
+
#
|
113
|
+
def initialize **context
|
114
|
+
@context = context
|
70
115
|
end
|
116
|
+
|
117
|
+
##
|
118
|
+
# A keyed hash of context information. Common context keys include:
|
119
|
+
#
|
120
|
+
# * **:logger** (`Logger`) A logger for use by this function call.
|
121
|
+
# * **:function_name** (`String`) The name of the running function.
|
122
|
+
# * **:function_type** (`Symbol`) The type of the running function,
|
123
|
+
# either `:http` or `:cloud_event`.
|
124
|
+
#
|
125
|
+
# @return [Hash]
|
126
|
+
#
|
127
|
+
attr_reader :context
|
71
128
|
end
|
72
129
|
end
|
73
130
|
end
|