Skip to content

Commit 13be77e

Browse files
author
Adriano Santos
committed
initial project structure
0 parents  commit 13be77e

24 files changed

+2887
-0
lines changed

Makefile

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
GOOGLE_PROTO_ROOT = protos/
2+
GOOGLE_PROTO_FILES = \
3+
google/protobuf/descriptor.proto \
4+
google/protobuf/any.proto \
5+
google/api/http.proto \
6+
google/api/annotations.proto
7+
8+
SPAWN_PROTO_ROOT = protos/eigr
9+
SPAWN_PROTO_FILES = \
10+
spawn/actors/actor.proto \
11+
spawn/actors/state.proto \
12+
spawn/actors/protocol.proto \
13+
spawn/actors/extensions.proto \
14+
spawn/actors/healthcheck.proto \
15+
spawn/actors/test.proto
16+
17+
.PHONY: all
18+
19+
all: build compile-proto install
20+
21+
# Tasks
22+
build: clean deps
23+
echo "Building the project..."
24+
25+
clean:
26+
echo "Cleaning up..."
27+
28+
deps:
29+
echo "Installing dependencies..."
30+
sudo luarocks install lua-protobuf
31+
sudo luarocks install luasocket
32+
sudo luarocks install lua-cjson
33+
34+
install: build
35+
echo "Installing the project..."
36+
luarocks make --local spawn-sdk-0.1.0.rockspec
37+
38+
test:
39+
go test -v ./...
40+
41+
compile-proto:
42+
echo "Compiling protobuf files..."
43+
protoc --lua_out=src/generated/ \
44+
-I=${GOOGLE_PROTO_ROOT} \
45+
${GOOGLE_PROTO_FILES}
46+
47+
protoc --lua_out=src/generated/ \
48+
-I=${SPAWN_PROTO_ROOT} \
49+
${SPAWN_PROTO_FILES}
50+
51+
52+
53+

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Lua Spawn SDK

examples/joe_actor.lua

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
local spawn = require "eigr.spawn"
2+
local StatefulActor = spawn.Actors.StatefulActor
3+
local ActorBehavior = spawn.Actors.ActorBehavior
4+
local ActionBindings = spawn.Actors.ActionBindings
5+
local Value = spawn.Actors.Value
6+
7+
local Request = require "domain_pb".Request
8+
local Reply = require "domain_pb".Reply
9+
local State = require "domain_pb".State
10+
11+
local JoeActor = StatefulActor:new()
12+
13+
function JoeActor:configure(context)
14+
return ActorBehavior.named("JoeActor")
15+
:channel("test.channel")
16+
:action("SetLanguage", ActionBindings.of(Request, self.setLanguage))
17+
end
18+
19+
function JoeActor:setLanguage(context, msg)
20+
local prev_state = context:get_state()
21+
-- Do something with state if needed
22+
23+
return Value.at()
24+
:response(Reply:new({response = "Hi " .. msg.language .. ". Hello From Lua"}))
25+
:state(self:updateState(msg.language))
26+
:reply()
27+
end
28+
29+
function JoeActor:updateState(language)
30+
return State:new({languages = {language}})
31+
end
32+
33+
return JoeActor

protos/eigr/spawn/actors/actor.proto

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
syntax = "proto3";
2+
3+
package spawn.actors;
4+
5+
import "google/protobuf/any.proto";
6+
import "google/protobuf/timestamp.proto";
7+
8+
option java_package = "io.spawn.actors";
9+
option go_package = "github.com/eigr/go-support/eigr/actors;actors";
10+
11+
message Registry {
12+
map<string, Actor> actors = 1;
13+
}
14+
15+
message ActorSystem {
16+
string name = 1;
17+
Registry registry = 2;
18+
}
19+
20+
// A strategy for save state.
21+
message ActorSnapshotStrategy {
22+
oneof strategy {
23+
// the timeout strategy.
24+
TimeoutStrategy timeout = 1;
25+
}
26+
}
27+
28+
// A strategy which a user function's entity is passivated.
29+
message ActorDeactivationStrategy {
30+
oneof strategy {
31+
// the timeout strategy.
32+
TimeoutStrategy timeout = 1;
33+
}
34+
}
35+
36+
// A strategy based on a timeout.
37+
message TimeoutStrategy {
38+
// The timeout in millis
39+
int64 timeout = 1;
40+
}
41+
42+
// A action represents an action that the user can perform on an Actor.
43+
// Actions in supporting languages are represented by functions or methods.
44+
// An Actor action has nothing to do with the semantics of Actions in a
45+
// CQRS/EventSourced system. It just represents an action that supporting
46+
// languages can invoke.
47+
message Action {
48+
49+
// The name of the function or method in the supporting language that has been
50+
// registered in Ator.
51+
string name = 1;
52+
}
53+
54+
// A FixedTimerAction is similar to a regular Action, its main differences are
55+
// that it is scheduled to run at regular intervals and only takes the actor's
56+
// state as an argument. Timer Actions are good for executing loops that
57+
// manipulate the actor's own state. In Elixir or other languages in BEAM it
58+
// would be similar to invoking Process.send_after(self(), atom, msg, timeout)
59+
message FixedTimerAction {
60+
61+
// The time to wait until the action is triggered
62+
int32 seconds = 1;
63+
64+
// See Action description Above
65+
Action action = 2;
66+
}
67+
68+
message ActorState {
69+
map<string, string> tags = 1;
70+
google.protobuf.Any state = 2;
71+
}
72+
73+
// Metadata represents a set of key-value pairs that can be used to
74+
// provide additional information about an Actor.
75+
message Metadata {
76+
// A channel group represents a way to send actions to various actors
77+
// that belong to a certain semantic group. Following the Pub-Sub pattern.
78+
repeated Channel channel_group = 1;
79+
80+
map<string, string> tags = 2;
81+
}
82+
83+
// Represents a Pub-Sub binding, where a actor can be subscribed to a channel
84+
// and map a specific action to a specific topic if necessary
85+
// if the action is not informed, the default action will be "receive".
86+
message Channel {
87+
string topic = 1;
88+
string action = 2;
89+
}
90+
91+
// The type that defines the runtime characteristics of the Actor.
92+
// Regardless of the type of actor it is important that
93+
// all actors are registered during the proxy and host initialization phase.
94+
enum Kind {
95+
// When no type is informed, the default to be assumed will be the Named
96+
// pattern.
97+
UNKNOW_KIND = 0;
98+
99+
// NAMED actors as the name suggests have only one real instance of themselves
100+
// running during their entire lifecycle. That is, they are the opposite of
101+
// the UNNAMED type Actors.
102+
NAMED = 1;
103+
104+
// UNNAMED actors are used to create children of this based actor at runtime
105+
UNNAMED = 2;
106+
107+
// Pooled Actors are similar to Unnamed actors, but unlike them,
108+
// their identifying name will always be the one registered at the system
109+
// initialization stage. The great advantage of Pooled actors is that they
110+
// have multiple instances of themselves acting as a request service pool.
111+
// Pooled actors are also stateless actors, that is, they will not have their
112+
// in-memory state persisted via Statesstore. This is done to avoid problems
113+
// with the correctness of the stored state.
114+
// Pooled Actors are generally used for tasks where the Actor Model would
115+
// perform worse than other concurrency models and for tasks that do not
116+
// require state concerns. Integration flows, data caching, proxies are good
117+
// examples of use cases for this type of Actor.
118+
POOLED = 3;
119+
120+
// Reserved for future use
121+
PROXY = 4;
122+
123+
TASK = 5;
124+
125+
// Projection actors are used to project data from different actor streams.
126+
PROJECTION = 6;
127+
}
128+
129+
message ProjectionSubject {
130+
string actor = 1;
131+
string source_action = 2;
132+
string action = 3;
133+
google.protobuf.Timestamp start_time = 4;
134+
}
135+
136+
message EventsRetentionStrategy {
137+
oneof strategy {
138+
int64 duration_ms = 1;
139+
bool infinite = 2;
140+
}
141+
}
142+
143+
message ProjectionSettings {
144+
// Define this for projections that need to listen to events
145+
repeated ProjectionSubject subjects = 1;
146+
147+
// Define this for actors that can emit events
148+
bool sourceable = 2;
149+
150+
// The strategy for event store retention
151+
EventsRetentionStrategy events_retention_strategy = 3;
152+
153+
// Define how we consume events from subjects
154+
bool strict_events_ordering = 4;
155+
}
156+
157+
message ActorSettings {
158+
159+
// Indicates the type of Actor to be configured.
160+
Kind kind = 1;
161+
162+
// Indicates whether an actor's state should be persisted in a definitive
163+
// store.
164+
bool stateful = 2;
165+
166+
// Snapshot strategy
167+
ActorSnapshotStrategy snapshot_strategy = 3;
168+
169+
// Deactivate strategy
170+
ActorDeactivationStrategy deactivation_strategy = 4;
171+
172+
// When kind is POOLED this is used to define minimun actor instances
173+
int32 min_pool_size = 5;
174+
175+
// When kind is POOLED this is used to define maximum actor instances
176+
int32 max_pool_size = 6;
177+
178+
// Event source settings
179+
ProjectionSettings projection_settings = 7;
180+
181+
// Actor's state type
182+
string state_type = 8;
183+
}
184+
185+
message ActorId {
186+
// The name of a Actor Entity.
187+
string name = 1;
188+
189+
// Name of a ActorSystem
190+
string system = 2;
191+
192+
// When the Actor is of the Unnamed type,
193+
// the name of the parent Actor must be informed here.
194+
string parent = 3;
195+
}
196+
197+
message Actor {
198+
// Actor Identification
199+
ActorId id = 1;
200+
201+
// A Actor state.
202+
ActorState state = 2;
203+
204+
// Actor metadata
205+
Metadata metadata = 6;
206+
207+
// Actor settings.
208+
ActorSettings settings = 3;
209+
210+
// The actions registered for an actor
211+
repeated Action actions = 4;
212+
213+
// The registered timer actions for an actor.
214+
repeated FixedTimerAction timer_actions = 5;
215+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
syntax = "proto3";
2+
3+
package spawn.actors;
4+
5+
import "google/protobuf/descriptor.proto";
6+
import "spawn/actors/actor.proto";
7+
8+
message ActorOpts {
9+
string state_type = 1;
10+
bool stateful = 2;
11+
int64 deactivate_timeout = 3;
12+
int64 snapshot_interval = 4;
13+
bool sourceable = 5;
14+
bool strict_events_ordering = 6;
15+
spawn.actors.EventsRetentionStrategy events_retention_strategy = 7;
16+
repeated spawn.actors.ProjectionSubject subjects = 8;
17+
spawn.actors.Kind kind = 9;
18+
}
19+
20+
message ActorViewOption {
21+
string query = 1;
22+
string map_to = 2;
23+
int32 page_size = 3;
24+
}
25+
26+
extend google.protobuf.FieldOptions {
27+
bool actor_id = 9999;
28+
}
29+
30+
extend google.protobuf.FieldOptions {
31+
bool searchable = 4890129;
32+
}
33+
34+
extend google.protobuf.MethodOptions {
35+
ActorViewOption view = 4890127;
36+
}
37+
38+
extend google.protobuf.ServiceOptions {
39+
ActorOpts actor = 4890128;
40+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
syntax = "proto3";
2+
3+
option objc_class_prefix = "HLW";
4+
5+
import "google/api/annotations.proto";
6+
import "google/protobuf/empty.proto";
7+
import "google/protobuf/timestamp.proto";
8+
import "spawn/actors/extensions.proto";
9+
10+
package spawn.actors.healthcheck;
11+
12+
message Status {
13+
string status = 1;
14+
string details = 2;
15+
google.protobuf.Timestamp updated_at = 3;
16+
}
17+
18+
// The state of HealthCheckActor
19+
message HealthCheckReply { Status status = 1; }
20+
21+
// The HealthCheck actor service definition.
22+
service HealthCheckActor {
23+
option (spawn.actors.actor) = {
24+
kind: NAMED
25+
stateful: false
26+
state_type: ".google.protobuf.Empty"
27+
snapshot_interval: 120000
28+
deactivate_timeout: 12000
29+
};
30+
31+
// Get Pong Message
32+
rpc Liveness(google.protobuf.Empty) returns (HealthCheckReply) {
33+
option (google.api.http) = {
34+
get: "/health/liveness"
35+
};
36+
}
37+
38+
rpc Readiness(google.protobuf.Empty) returns (HealthCheckReply) {
39+
option (google.api.http) = {
40+
get: "/health/readiness"
41+
};
42+
}
43+
}

0 commit comments

Comments
 (0)