-
Notifications
You must be signed in to change notification settings - Fork 249
/
actor.h
149 lines (111 loc) · 4.67 KB
/
actor.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Copyright (c) 2017-2022 Cloudflare, Inc.
// Licensed under the Apache 2.0 license found in the LICENSE file or at:
// https://opensource.org/licenses/Apache-2.0
#pragma once
// "Actors" are the internal name for Durable Objects, because they implement a sort of actor
// model. We ended up not calling the product "Actors" publicly because we found that people who
// were familiar with actor-model programming were more confused than helped by it -- they tended
// to expect something that looked more specifically like Erlang, whereas our actors are much more
// abstractly related.
#include <kj/async.h>
#include <capnp/compat/byte-stream.h>
#include <capnp/compat/http-over-capnp.h>
#include <workerd/api/http.h>
#include <workerd/jsg/jsg.h>
#include <workerd/io/io-context.h>
namespace workerd::api {
class ColoLocalActorNamespace: public jsg::Object {
// A capability to an ephemeral Actor namespace.
public:
ColoLocalActorNamespace(uint channel)
: channel(channel) {}
jsg::Ref<Fetcher> get(kj::String actorId);
JSG_RESOURCE_TYPE(ColoLocalActorNamespace) {
JSG_METHOD(get);
}
private:
uint channel;
};
class DurableObjectNamespace;
class DurableObjectId: public jsg::Object {
// DurableObjectId type seen by JavaScript.
public:
DurableObjectId(kj::Own<ActorIdFactory::ActorId> id): id(kj::mv(id)) {}
const ActorIdFactory::ActorId& getInner() { return *id; }
// ---------------------------------------------------------------------------
// JS API
kj::String toString();
// Converts to a string which can be passed back to the constructor to reproduce the same ID.
inline bool equals(DurableObjectId& other) { return id->equals(*other.id); }
inline jsg::Optional<kj::StringPtr> getName() { return id->getName(); }
// Get the name, if known.
JSG_RESOURCE_TYPE(DurableObjectId) {
JSG_METHOD(toString);
JSG_METHOD(equals);
JSG_READONLY_INSTANCE_PROPERTY(name, getName);
}
private:
kj::Own<ActorIdFactory::ActorId> id;
friend class DurableObjectNamespace;
};
class DurableObject: public Fetcher {
// Stub object used to send messages to a remote durable object.
public:
DurableObject(jsg::Ref<DurableObjectId> id, IoOwn<OutgoingFactory> outgoingFactory,
RequiresHostAndProtocol requiresHost)
: Fetcher(kj::mv(outgoingFactory), requiresHost, true /* isInHouse */),
id(kj::mv(id)) {}
jsg::Ref<DurableObjectId> getId(v8::Isolate* isolate) { return id.addRef(); };
jsg::Optional<kj::StringPtr> getName() { return id->getName(); }
JSG_RESOURCE_TYPE(DurableObject) {
JSG_INHERIT(Fetcher);
JSG_READONLY_INSTANCE_PROPERTY(id, getId);
JSG_READONLY_INSTANCE_PROPERTY(name, getName);
}
private:
jsg::Ref<DurableObjectId> id;
void visitForGc(jsg::GcVisitor& visitor) {
visitor.visit(id);
}
};
class DurableObjectNamespace: public jsg::Object {
// Global durable object class binding type.
public:
DurableObjectNamespace(uint channel, kj::Own<ActorIdFactory> idFactory)
: channel(channel), idFactory(kj::mv(idFactory)) {}
struct NewUniqueIdOptions {
jsg::Optional<kj::String> jurisdiction;
// Restricts the new unique ID to a set of colos within a jurisdiction.
JSG_STRUCT(jurisdiction);
};
jsg::Ref<DurableObjectId> newUniqueId(jsg::Optional<NewUniqueIdOptions> options);
// Create a new unique ID for a durable object that will be allocated nearby the calling colo.
jsg::Ref<DurableObjectId> idFromName(kj::String name);
// Create a name-derived ID. Passing in the same `name` (to the same class) will always
// produce the same ID.
jsg::Ref<DurableObjectId> idFromString(kj::String id);
// Create a DurableObjectId from the stringified form of the ID (as produced by calling
// `toString()` on a durable object ID). Throws if the ID is not a 64-digit hex number, or if the
// ID was not originally created for this class.
//
// The ID may be one that was originally created using either `newUniqueId()` or `idFromName()`.
jsg::Ref<DurableObject> get(
jsg::Ref<DurableObjectId> id, CompatibilityFlags::Reader featureFlags);
// Gets a durable object by ID or creates it if it doesn't already exist.
JSG_RESOURCE_TYPE(DurableObjectNamespace) {
JSG_METHOD(newUniqueId);
JSG_METHOD(idFromName);
JSG_METHOD(idFromString);
JSG_METHOD(get);
}
private:
uint channel;
kj::Own<ActorIdFactory> idFactory;
};
#define EW_ACTOR_ISOLATE_TYPES \
api::ColoLocalActorNamespace, \
api::DurableObject, \
api::DurableObjectId, \
api::DurableObjectNamespace, \
api::DurableObjectNamespace::NewUniqueIdOptions
} // namespace workerd::api