@effect/cluster 0.53.2 → 0.53.4
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.
- package/K8sHttpClient/package.json +6 -0
- package/dist/cjs/EntityResource.js +34 -19
- package/dist/cjs/EntityResource.js.map +1 -1
- package/dist/cjs/K8sHttpClient.js +164 -0
- package/dist/cjs/K8sHttpClient.js.map +1 -0
- package/dist/cjs/RunnerHealth.js +3 -63
- package/dist/cjs/RunnerHealth.js.map +1 -1
- package/dist/cjs/index.js +3 -1
- package/dist/dts/EntityResource.d.ts +23 -11
- package/dist/dts/EntityResource.d.ts.map +1 -1
- package/dist/dts/K8sHttpClient.d.ts +91 -0
- package/dist/dts/K8sHttpClient.d.ts.map +1 -0
- package/dist/dts/RunnerHealth.d.ts +3 -4
- package/dist/dts/RunnerHealth.d.ts.map +1 -1
- package/dist/dts/index.d.ts +4 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/esm/EntityResource.js +32 -18
- package/dist/esm/EntityResource.js.map +1 -1
- package/dist/esm/K8sHttpClient.js +153 -0
- package/dist/esm/K8sHttpClient.js.map +1 -0
- package/dist/esm/RunnerHealth.js +3 -63
- package/dist/esm/RunnerHealth.js.map +1 -1
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -1
- package/package.json +12 -1
- package/src/EntityResource.ts +53 -32
- package/src/K8sHttpClient.ts +240 -0
- package/src/RunnerHealth.ts +4 -79
- package/src/index.ts +5 -0
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @since 1.0.0
|
|
3
3
|
*/
|
|
4
|
-
import * as FileSystem from "@effect/platform/FileSystem";
|
|
5
|
-
import * as HttpClient from "@effect/platform/HttpClient";
|
|
6
4
|
import * as Context from "effect/Context";
|
|
7
5
|
import * as Effect from "effect/Effect";
|
|
8
6
|
import * as Layer from "effect/Layer";
|
|
9
7
|
import type * as Scope from "effect/Scope";
|
|
8
|
+
import * as K8s from "./K8sHttpClient.js";
|
|
10
9
|
import type { RunnerAddress } from "./RunnerAddress.js";
|
|
11
10
|
import * as Runners from "./Runners.js";
|
|
12
11
|
declare const RunnerHealth_base: Context.TagClass<RunnerHealth, "@effect/cluster/RunnerHealth", {
|
|
@@ -54,7 +53,7 @@ export declare const makeK8s: (options?: {
|
|
|
54
53
|
readonly labelSelector?: string | undefined;
|
|
55
54
|
} | undefined) => Effect.Effect<{
|
|
56
55
|
readonly isAlive: (address: RunnerAddress) => Effect.Effect<boolean>;
|
|
57
|
-
}, never,
|
|
56
|
+
}, never, K8s.K8sHttpClient>;
|
|
58
57
|
/**
|
|
59
58
|
* A layer which will check the Kubernetes API to see if a Runner is healthy.
|
|
60
59
|
*
|
|
@@ -70,6 +69,6 @@ export declare const makeK8s: (options?: {
|
|
|
70
69
|
export declare const layerK8s: (options?: {
|
|
71
70
|
readonly namespace?: string | undefined;
|
|
72
71
|
readonly labelSelector?: string | undefined;
|
|
73
|
-
} | undefined) => Layer.Layer<RunnerHealth, never,
|
|
72
|
+
} | undefined) => Layer.Layer<RunnerHealth, never, K8s.K8sHttpClient>;
|
|
74
73
|
export {};
|
|
75
74
|
//# sourceMappingURL=RunnerHealth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RunnerHealth.d.ts","sourceRoot":"","sources":["../../src/RunnerHealth.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"RunnerHealth.d.ts","sourceRoot":"","sources":["../../src/RunnerHealth.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAErC,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,GAAG,MAAM,oBAAoB,CAAA;AACzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;;sBAejB,CAAC,OAAO,EAAE,aAAa,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;;AAbxE;;;;;;;;;GASG;AACH,qBAAa,YAAa,SAAQ,iBAK/B;CAAG;AAEN;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,yCAEpB,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,CAClC,YAAY,CAAC,MAAM,CAAC,EACpB,KAAK,EACL,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC,KAAK,CAc7B,CAAA;AAEF;;;;;GAKG;AACH,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,KAAK,CACjC,YAAY,EACZ,KAAK,EACL,OAAO,CAAC,OAAO,CACuB,CAAA;AAExC;;;GAGG;AACH,eAAO,MAAM,OAAO;yBACG,MAAM,GAAG,SAAS;6BACd,MAAM,GAAG,SAAS;;sBAzDvB,CAAC,OAAO,EAAE,aAAa,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;4BAoEtE,CAAA;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,QAAQ,GACnB,UAAU;IACR,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC5C,GAAG,SAAS,KACZ,KAAK,CAAC,KAAK,CACZ,YAAY,EACZ,KAAK,EACL,GAAG,CAAC,aAAa,CAC8B,CAAA"}
|
package/dist/dts/index.d.ts
CHANGED
package/dist/dts/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAE/C;;GAEG;AACH,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AAEjD;;GAEG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AAErD;;GAEG;AACH,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AAEnD;;GAEG;AACH,OAAO,KAAK,qBAAqB,MAAM,4BAA4B,CAAA;AAEnE;;GAEG;AACH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAE3C;;GAEG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC;;GAEG;AACH,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AAEnD;;GAEG;AACH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AAEzC;;GAEG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAE/C;;GAEG;AACH,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAE3D;;GAEG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AAErD;;GAEG;AACH,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAE7C;;GAEG;AACH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AAEzC;;GAEG;AACH,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAE7C;;GAEG;AACH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAE3C;;GAEG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC;;GAEG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AAErD;;GAEG;AACH,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAEnC;;GAEG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC;;GAEG;AACH,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AAEnD;;GAEG;AACH,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AAEjD;;GAEG;AACH,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AAEjD;;GAEG;AACH,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AAEnD;;GAEG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC;;GAEG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC;;GAEG;AACH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AAEzC;;GAEG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AAErD;;GAEG;AACH,OAAO,KAAK,yBAAyB,MAAM,gCAAgC,CAAA;AAE3E;;GAEG;AACH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAE3C;;GAEG;AACH,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAA;AAEzD;;GAEG;AACH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAE3C;;GAEG;AACH,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AAEjD;;GAEG;AACH,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAE3D;;GAEG;AACH,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAE/C;;GAEG;AACH,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AAEjD;;GAEG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AAErD;;GAEG;AACH,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AAEnD;;GAEG;AACH,OAAO,KAAK,qBAAqB,MAAM,4BAA4B,CAAA;AAEnE;;GAEG;AACH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAE3C;;GAEG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC;;GAEG;AACH,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AAEnD;;GAEG;AACH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AAEzC;;GAEG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAE/C;;GAEG;AACH,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAE3D;;GAEG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AAErD;;GAEG;AACH,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAE7C;;GAEG;AACH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AAEzC;;GAEG;AACH,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAE7C;;GAEG;AACH,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AAEnD;;GAEG;AACH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAE3C;;GAEG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC;;GAEG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AAErD;;GAEG;AACH,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAEnC;;GAEG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC;;GAEG;AACH,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AAEnD;;GAEG;AACH,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AAEjD;;GAEG;AACH,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AAEjD;;GAEG;AACH,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AAEnD;;GAEG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC;;GAEG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC;;GAEG;AACH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AAEzC;;GAEG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AAErD;;GAEG;AACH,OAAO,KAAK,yBAAyB,MAAM,gCAAgC,CAAA;AAE3E;;GAEG;AACH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAE3C;;GAEG;AACH,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAA;AAEzD;;GAEG;AACH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAE3C;;GAEG;AACH,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AAEjD;;GAEG;AACH,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAE3D;;GAEG;AACH,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAA"}
|
|
@@ -1,17 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @since 1.0.0
|
|
3
3
|
*/
|
|
4
|
+
import * as Context from "effect/Context";
|
|
4
5
|
import * as Duration from "effect/Duration";
|
|
5
6
|
import * as Effect from "effect/Effect";
|
|
6
7
|
import { identity } from "effect/Function";
|
|
7
8
|
import * as RcRef from "effect/RcRef";
|
|
8
9
|
import * as Scope from "effect/Scope";
|
|
9
10
|
import * as Entity from "./Entity.js";
|
|
11
|
+
import * as K8sHttpClient from "./K8sHttpClient.js";
|
|
10
12
|
/**
|
|
11
13
|
* @since 1.0.0
|
|
12
14
|
* @category Type ids
|
|
13
15
|
*/
|
|
14
16
|
export const TypeId = "~@effect/cluster/EntityResource";
|
|
17
|
+
/**
|
|
18
|
+
* A `Scope` that is only closed when the resource is explicitly closed.
|
|
19
|
+
*
|
|
20
|
+
* It is not closed during restarts, due to shard movement or node shutdowns.
|
|
21
|
+
*
|
|
22
|
+
* @since 1.0.0
|
|
23
|
+
* @category Scope
|
|
24
|
+
*/
|
|
25
|
+
export class CloseScope extends /*#__PURE__*/Context.Tag("@effect/cluster/EntityResource/CloseScope")() {}
|
|
15
26
|
/**
|
|
16
27
|
* A `EntityResource` is a resource that can be acquired inside a cluster
|
|
17
28
|
* entity, which will keep the entity alive even across restarts.
|
|
@@ -26,28 +37,17 @@ export const TypeId = "~@effect/cluster/EntityResource";
|
|
|
26
37
|
* @category Constructors
|
|
27
38
|
*/
|
|
28
39
|
export const make = /*#__PURE__*/Effect.fnUntraced(function* (options) {
|
|
29
|
-
const shutdownMode = options.shutdownMode ?? "always";
|
|
30
40
|
let shuttingDown = false;
|
|
31
41
|
const ref = yield* RcRef.make({
|
|
32
42
|
acquire: Effect.gen(function* () {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
yield*
|
|
38
|
-
|
|
39
|
-
yield* Scope.close(closeable, exit);
|
|
40
|
-
yield* Entity.keepAlive(false);
|
|
41
|
-
}, Effect.provide(context)));
|
|
42
|
-
scope = closeable;
|
|
43
|
-
} else {
|
|
44
|
-
yield* Effect.addFinalizer(() => {
|
|
45
|
-
if (shuttingDown) return Effect.void;
|
|
46
|
-
return Entity.keepAlive(false);
|
|
47
|
-
});
|
|
48
|
-
}
|
|
43
|
+
const closeable = yield* Scope.make();
|
|
44
|
+
yield* Effect.addFinalizer(Effect.fnUntraced(function* (exit) {
|
|
45
|
+
if (shuttingDown) return;
|
|
46
|
+
yield* Scope.close(closeable, exit);
|
|
47
|
+
yield* Entity.keepAlive(false);
|
|
48
|
+
}));
|
|
49
49
|
yield* Entity.keepAlive(true);
|
|
50
|
-
return yield* options.acquire.pipe(
|
|
50
|
+
return yield* options.acquire.pipe(Effect.provideService(CloseScope, closeable));
|
|
51
51
|
}),
|
|
52
52
|
idleTimeToLive: options.idleTimeToLive ?? Duration.infinity
|
|
53
53
|
});
|
|
@@ -63,4 +63,18 @@ export const make = /*#__PURE__*/Effect.fnUntraced(function* (options) {
|
|
|
63
63
|
close: RcRef.invalidate(ref)
|
|
64
64
|
});
|
|
65
65
|
});
|
|
66
|
+
/**
|
|
67
|
+
* @since 1.0.0
|
|
68
|
+
* @category Kubernetes
|
|
69
|
+
*/
|
|
70
|
+
export const makeK8sPod = /*#__PURE__*/Effect.fnUntraced(function* (spec, options) {
|
|
71
|
+
const createPod = yield* K8sHttpClient.makeCreatePod;
|
|
72
|
+
return yield* make({
|
|
73
|
+
...options,
|
|
74
|
+
acquire: Effect.gen(function* () {
|
|
75
|
+
const scope = yield* CloseScope;
|
|
76
|
+
return yield* createPod(spec).pipe(Scope.extend(scope));
|
|
77
|
+
})
|
|
78
|
+
});
|
|
79
|
+
});
|
|
66
80
|
//# sourceMappingURL=EntityResource.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityResource.js","names":["Duration","Effect","identity","RcRef","Scope","Entity","TypeId","make","fnUntraced","options","
|
|
1
|
+
{"version":3,"file":"EntityResource.js","names":["Context","Duration","Effect","identity","RcRef","Scope","Entity","K8sHttpClient","TypeId","CloseScope","Tag","make","fnUntraced","options","shuttingDown","ref","acquire","gen","closeable","addFinalizer","exit","close","keepAlive","pipe","provideService","idleTimeToLive","infinity","void","scoped","get","invalidate","makeK8sPod","spec","createPod","makeCreatePod","scope","extend"],"sources":["../../src/EntityResource.ts"],"sourcesContent":[null],"mappings":"AAAA;;;AAGA,OAAO,KAAKA,OAAO,MAAM,gBAAgB;AACzC,OAAO,KAAKC,QAAQ,MAAM,iBAAiB;AAC3C,OAAO,KAAKC,MAAM,MAAM,eAAe;AACvC,SAASC,QAAQ,QAAQ,iBAAiB;AAC1C,OAAO,KAAKC,KAAK,MAAM,cAAc;AACrC,OAAO,KAAKC,KAAK,MAAM,cAAc;AAErC,OAAO,KAAKC,MAAM,MAAM,aAAa;AACrC,OAAO,KAAKC,aAAa,MAAM,oBAAoB;AAGnD;;;;AAIA,OAAO,MAAMC,MAAM,GAAW,iCAAiC;AAkB/D;;;;;;;;AAQA,OAAM,MAAOC,UAAW,sBAAQT,OAAO,CAACU,GAAG,CAAC,2CAA2C,CAAC,EAGrF;AAEH;;;;;;;;;;;;;AAaA,OAAO,MAAMC,IAAI,gBAObT,MAAM,CAACU,UAAU,CAAC,WAAmBC,OAGxC;EACC,IAAIC,YAAY,GAAG,KAAK;EAExB,MAAMC,GAAG,GAAG,OAAOX,KAAK,CAACO,IAAI,CAAC;IAC5BK,OAAO,EAAEd,MAAM,CAACe,GAAG,CAAC,aAAS;MAC3B,MAAMC,SAAS,GAAG,OAAOb,KAAK,CAACM,IAAI,EAAE;MAErC,OAAOT,MAAM,CAACiB,YAAY,CACxBjB,MAAM,CAACU,UAAU,CAAC,WAAUQ,IAAI;QAC9B,IAAIN,YAAY,EAAE;QAClB,OAAOT,KAAK,CAACgB,KAAK,CAACH,SAAS,EAAEE,IAAI,CAAC;QACnC,OAAOd,MAAM,CAACgB,SAAS,CAAC,KAAK,CAAC;MAChC,CAAC,CAAC,CACH;MAED,OAAOhB,MAAM,CAACgB,SAAS,CAAC,IAAI,CAAC;MAE7B,OAAO,OAAOT,OAAO,CAACG,OAAO,CAACO,IAAI,CAChCrB,MAAM,CAACsB,cAAc,CAACf,UAAU,EAAES,SAAS,CAAC,CAC7C;IACH,CAAC,CAAC;IACFO,cAAc,EAAEZ,OAAO,CAACY,cAAc,IAAIxB,QAAQ,CAACyB;GACpD,CAAC;EAEF,OAAOxB,MAAM,CAACiB,YAAY,CAAC,MAAK;IAC9BL,YAAY,GAAG,IAAI;IACnB,OAAOZ,MAAM,CAACyB,IAAI;EACpB,CAAC,CAAC;EAEF;EACA,OAAOzB,MAAM,CAAC0B,MAAM,CAACxB,KAAK,CAACyB,GAAG,CAACd,GAAG,CAAC,CAAC;EAEpC,OAAOZ,QAAQ,CAAuB;IACpC,CAACK,MAAM,GAAGA,MAAM;IAChBqB,GAAG,EAAEzB,KAAK,CAACyB,GAAG,CAACd,GAAG,CAAC;IACnBM,KAAK,EAAEjB,KAAK,CAAC0B,UAAU,CAACf,GAAG;GAC5B,CAAC;AACJ,CAAC,CAAC;AAEF;;;;AAIA,OAAO,MAAMgB,UAAU,gBASnB7B,MAAM,CAACU,UAAU,CAAC,WAAUoB,IAAY,EAAEnB,OAE7C;EACC,MAAMoB,SAAS,GAAG,OAAO1B,aAAa,CAAC2B,aAAa;EACpD,OAAO,OAAOvB,IAAI,CAAC;IACjB,GAAGE,OAAO;IACVG,OAAO,EAAEd,MAAM,CAACe,GAAG,CAAC,aAAS;MAC3B,MAAMkB,KAAK,GAAG,OAAO1B,UAAU;MAC/B,OAAO,OAAOwB,SAAS,CAACD,IAAI,CAAC,CAACT,IAAI,CAChClB,KAAK,CAAC+B,MAAM,CAACD,KAAK,CAAC,CACpB;IACH,CAAC;GACF,CAAC;AACJ,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since 1.0.0
|
|
3
|
+
*/
|
|
4
|
+
import * as FileSystem from "@effect/platform/FileSystem";
|
|
5
|
+
import * as HttpClient from "@effect/platform/HttpClient";
|
|
6
|
+
import * as HttpClientRequest from "@effect/platform/HttpClientRequest";
|
|
7
|
+
import * as HttpClientResponse from "@effect/platform/HttpClientResponse";
|
|
8
|
+
import * as Context from "effect/Context";
|
|
9
|
+
import * as Effect from "effect/Effect";
|
|
10
|
+
import { identity } from "effect/Function";
|
|
11
|
+
import * as Layer from "effect/Layer";
|
|
12
|
+
import * as Option from "effect/Option";
|
|
13
|
+
import * as Schedule from "effect/Schedule";
|
|
14
|
+
import * as Schema from "effect/Schema";
|
|
15
|
+
/**
|
|
16
|
+
* @since 1.0.0
|
|
17
|
+
* @category Tags
|
|
18
|
+
*/
|
|
19
|
+
export class K8sHttpClient extends /*#__PURE__*/Context.Tag("@effect/cluster/K8sHttpClient")() {}
|
|
20
|
+
/**
|
|
21
|
+
* @since 1.0.0
|
|
22
|
+
* @category Layers
|
|
23
|
+
*/
|
|
24
|
+
export const layer = /*#__PURE__*/Layer.effect(K8sHttpClient, /*#__PURE__*/Effect.gen(function* () {
|
|
25
|
+
const fs = yield* FileSystem.FileSystem;
|
|
26
|
+
const token = yield* fs.readFileString("/var/run/secrets/kubernetes.io/serviceaccount/token").pipe(Effect.option);
|
|
27
|
+
return (yield* HttpClient.HttpClient).pipe(HttpClient.mapRequest(HttpClientRequest.prependUrl("https://kubernetes.default.svc/api")), token._tag === "Some" ? HttpClient.mapRequest(HttpClientRequest.bearerToken(token.value.trim())) : identity, HttpClient.filterStatusOk, HttpClient.retryTransient({
|
|
28
|
+
schedule: Schedule.spaced(5000)
|
|
29
|
+
}));
|
|
30
|
+
}));
|
|
31
|
+
/**
|
|
32
|
+
* @since 1.0.0
|
|
33
|
+
* @category Constructors
|
|
34
|
+
*/
|
|
35
|
+
export const makeGetPods = /*#__PURE__*/Effect.fnUntraced(function* (options) {
|
|
36
|
+
const client = yield* K8sHttpClient;
|
|
37
|
+
const getPods = HttpClientRequest.get(options?.namespace ? `/v1/namespaces/${options.namespace}/pods` : "/v1/pods").pipe(HttpClientRequest.setUrlParam("fieldSelector", "status.phase=Running"), options?.labelSelector ? HttpClientRequest.setUrlParam("labelSelector", options.labelSelector) : identity);
|
|
38
|
+
return yield* client.execute(getPods).pipe(Effect.flatMap(HttpClientResponse.schemaBodyJson(PodList)), Effect.map(list => {
|
|
39
|
+
const pods = new Map();
|
|
40
|
+
for (let i = 0; i < list.items.length; i++) {
|
|
41
|
+
const pod = list.items[i];
|
|
42
|
+
pods.set(pod.status.podIP, pod);
|
|
43
|
+
}
|
|
44
|
+
return pods;
|
|
45
|
+
}), Effect.tapErrorCause(cause => Effect.logWarning("Failed to fetch pods from Kubernetes API", cause)), Effect.cachedWithTTL("10 seconds"));
|
|
46
|
+
});
|
|
47
|
+
/**
|
|
48
|
+
* @since 1.0.0
|
|
49
|
+
* @category Constructors
|
|
50
|
+
*/
|
|
51
|
+
export const makeCreatePod = /*#__PURE__*/Effect.gen(function* () {
|
|
52
|
+
const client = yield* K8sHttpClient;
|
|
53
|
+
return Effect.fnUntraced(function* (spec) {
|
|
54
|
+
spec = {
|
|
55
|
+
apiVersion: "v1",
|
|
56
|
+
kind: "Pod",
|
|
57
|
+
metadata: {
|
|
58
|
+
namespace: "default",
|
|
59
|
+
...spec.metadata
|
|
60
|
+
},
|
|
61
|
+
...spec
|
|
62
|
+
};
|
|
63
|
+
const namespace = spec.metadata?.namespace ?? "default";
|
|
64
|
+
const name = spec.metadata.name;
|
|
65
|
+
const readPodRaw = HttpClientRequest.get(`/v1/namespaces/${namespace}/pods/${name}`).pipe(client.execute);
|
|
66
|
+
const readPod = readPodRaw.pipe(Effect.flatMap(HttpClientResponse.schemaBodyJson(Pod)), Effect.asSome, Effect.retry({
|
|
67
|
+
while: e => e._tag === "ParseError",
|
|
68
|
+
schedule: Schedule.spaced("1 seconds")
|
|
69
|
+
}), Effect.catchIf(err => err._tag === "ResponseError" && err.response.status === 404, () => Effect.succeedNone), Effect.orDie);
|
|
70
|
+
const isPodFound = readPodRaw.pipe(Effect.as(true), Effect.catchIf(err => err._tag === "ResponseError" && err.response.status === 404, () => Effect.succeed(false)));
|
|
71
|
+
const createPod = HttpClientRequest.post(`/v1/namespaces/${namespace}/pods`).pipe(HttpClientRequest.bodyUnsafeJson(spec), client.execute, Effect.catchIf(err => err._tag === "ResponseError" && err.response.status === 409, () => readPod), Effect.tapErrorCause(Effect.logInfo), Effect.orDie);
|
|
72
|
+
const deletePod = HttpClientRequest.del(`/v1/namespaces/${namespace}/pods/${name}`).pipe(client.execute, Effect.flatMap(res => res.json), Effect.catchIf(err => err._tag === "ResponseError" && err.response.status === 404, () => Effect.void), Effect.tapErrorCause(Effect.logInfo), Effect.orDie, Effect.asVoid);
|
|
73
|
+
yield* Effect.addFinalizer(Effect.fnUntraced(function* () {
|
|
74
|
+
yield* deletePod;
|
|
75
|
+
yield* isPodFound.pipe(Effect.repeat({
|
|
76
|
+
until: found => !found,
|
|
77
|
+
schedule: Schedule.spaced("3 seconds")
|
|
78
|
+
}), Effect.orDie);
|
|
79
|
+
}));
|
|
80
|
+
let opod = Option.none();
|
|
81
|
+
while (Option.isNone(opod) || !opod.value.isReady) {
|
|
82
|
+
if (Option.isNone(opod)) {
|
|
83
|
+
yield* createPod;
|
|
84
|
+
}
|
|
85
|
+
yield* Effect.sleep("3 seconds");
|
|
86
|
+
opod = yield* readPod;
|
|
87
|
+
}
|
|
88
|
+
return opod.value.status;
|
|
89
|
+
}, Effect.withSpan("K8sHttpClient.createPod"));
|
|
90
|
+
});
|
|
91
|
+
/**
|
|
92
|
+
* @since 1.0.0
|
|
93
|
+
* @category Schemas
|
|
94
|
+
*/
|
|
95
|
+
export class PodStatus extends /*#__PURE__*/Schema.Class("@effect/cluster/K8sHttpClient/PodStatus")({
|
|
96
|
+
phase: Schema.String,
|
|
97
|
+
conditions: /*#__PURE__*/Schema.Array(/*#__PURE__*/Schema.Struct({
|
|
98
|
+
type: Schema.String,
|
|
99
|
+
status: Schema.String,
|
|
100
|
+
lastTransitionTime: Schema.String
|
|
101
|
+
})),
|
|
102
|
+
podIP: Schema.String,
|
|
103
|
+
hostIP: Schema.String
|
|
104
|
+
}) {}
|
|
105
|
+
/**
|
|
106
|
+
* @since 1.0.0
|
|
107
|
+
* @category Schemas
|
|
108
|
+
*/
|
|
109
|
+
export class Pod extends /*#__PURE__*/Schema.Class("@effect/cluster/K8sHttpClient/Pod")({
|
|
110
|
+
status: PodStatus
|
|
111
|
+
}) {
|
|
112
|
+
get isReady() {
|
|
113
|
+
for (let i = 0; i < this.status.conditions.length; i++) {
|
|
114
|
+
const condition = this.status.conditions[i];
|
|
115
|
+
if (condition.type === "Ready") {
|
|
116
|
+
return condition.status === "True";
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
get isReadyOrInitializing() {
|
|
122
|
+
let initializedAt;
|
|
123
|
+
let readyAt;
|
|
124
|
+
for (let i = 0; i < this.status.conditions.length; i++) {
|
|
125
|
+
const condition = this.status.conditions[i];
|
|
126
|
+
switch (condition.type) {
|
|
127
|
+
case "Initialized":
|
|
128
|
+
{
|
|
129
|
+
if (condition.status !== "True") {
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
initializedAt = condition.lastTransitionTime;
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
case "Ready":
|
|
136
|
+
{
|
|
137
|
+
if (condition.status === "True") {
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
readyAt = condition.lastTransitionTime;
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// if the pod is still booting up, consider it ready as it would have
|
|
146
|
+
// already registered itself with RunnerStorage by now
|
|
147
|
+
return initializedAt === readyAt;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const PodList = /*#__PURE__*/Schema.Struct({
|
|
151
|
+
items: /*#__PURE__*/Schema.Array(Pod)
|
|
152
|
+
});
|
|
153
|
+
//# sourceMappingURL=K8sHttpClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"K8sHttpClient.js","names":["FileSystem","HttpClient","HttpClientRequest","HttpClientResponse","Context","Effect","identity","Layer","Option","Schedule","Schema","K8sHttpClient","Tag","layer","effect","gen","fs","token","readFileString","pipe","option","mapRequest","prependUrl","_tag","bearerToken","value","trim","filterStatusOk","retryTransient","schedule","spaced","makeGetPods","fnUntraced","options","client","getPods","get","namespace","setUrlParam","labelSelector","execute","flatMap","schemaBodyJson","PodList","map","list","pods","Map","i","items","length","pod","set","status","podIP","tapErrorCause","cause","logWarning","cachedWithTTL","makeCreatePod","spec","apiVersion","kind","metadata","name","readPodRaw","readPod","Pod","asSome","retry","while","e","catchIf","err","response","succeedNone","orDie","isPodFound","as","succeed","createPod","post","bodyUnsafeJson","logInfo","deletePod","del","res","json","void","asVoid","addFinalizer","repeat","until","found","opod","none","isNone","isReady","sleep","withSpan","PodStatus","Class","phase","String","conditions","Array","Struct","type","lastTransitionTime","hostIP","condition","isReadyOrInitializing","initializedAt","readyAt"],"sources":["../../src/K8sHttpClient.ts"],"sourcesContent":[null],"mappings":"AAAA;;;AAGA,OAAO,KAAKA,UAAU,MAAM,6BAA6B;AACzD,OAAO,KAAKC,UAAU,MAAM,6BAA6B;AAEzD,OAAO,KAAKC,iBAAiB,MAAM,oCAAoC;AACvE,OAAO,KAAKC,kBAAkB,MAAM,qCAAqC;AACzE,OAAO,KAAKC,OAAO,MAAM,gBAAgB;AACzC,OAAO,KAAKC,MAAM,MAAM,eAAe;AACvC,SAASC,QAAQ,QAAQ,iBAAiB;AAC1C,OAAO,KAAKC,KAAK,MAAM,cAAc;AACrC,OAAO,KAAKC,MAAM,MAAM,eAAe;AAEvC,OAAO,KAAKC,QAAQ,MAAM,iBAAiB;AAC3C,OAAO,KAAKC,MAAM,MAAM,eAAe;AAGvC;;;;AAIA,OAAM,MAAOC,aAAc,sBAAQP,OAAO,CAACQ,GAAG,CAAC,+BAA+B,CAAC,EAG5E;AAEH;;;;AAIA,OAAO,MAAMC,KAAK,gBAIdN,KAAK,CAACO,MAAM,CACdH,aAAa,eACbN,MAAM,CAACU,GAAG,CAAC,aAAS;EAClB,MAAMC,EAAE,GAAG,OAAOhB,UAAU,CAACA,UAAU;EACvC,MAAMiB,KAAK,GAAG,OAAOD,EAAE,CAACE,cAAc,CAAC,qDAAqD,CAAC,CAACC,IAAI,CAChGd,MAAM,CAACe,MAAM,CACd;EACD,OAAO,CAAC,OAAOnB,UAAU,CAACA,UAAU,EAAEkB,IAAI,CACxClB,UAAU,CAACoB,UAAU,CAACnB,iBAAiB,CAACoB,UAAU,CAAC,oCAAoC,CAAC,CAAC,EACzFL,KAAK,CAACM,IAAI,KAAK,MAAM,GAAGtB,UAAU,CAACoB,UAAU,CAACnB,iBAAiB,CAACsB,WAAW,CAACP,KAAK,CAACQ,KAAK,CAACC,IAAI,EAAE,CAAC,CAAC,GAAGpB,QAAQ,EAC3GL,UAAU,CAAC0B,cAAc,EACzB1B,UAAU,CAAC2B,cAAc,CAAC;IACxBC,QAAQ,EAAEpB,QAAQ,CAACqB,MAAM,CAAC,IAAI;GAC/B,CAAC,CACH;AACH,CAAC,CAAC,CACH;AAED;;;;AAIA,OAAO,MAAMC,WAAW,gBASpB1B,MAAM,CAAC2B,UAAU,CAAC,WAAUC,OAG/B;EACC,MAAMC,MAAM,GAAG,OAAOvB,aAAa;EAEnC,MAAMwB,OAAO,GAAGjC,iBAAiB,CAACkC,GAAG,CACnCH,OAAO,EAAEI,SAAS,GAAG,kBAAkBJ,OAAO,CAACI,SAAS,OAAO,GAAG,UAAU,CAC7E,CAAClB,IAAI,CACJjB,iBAAiB,CAACoC,WAAW,CAAC,eAAe,EAAE,sBAAsB,CAAC,EACtEL,OAAO,EAAEM,aAAa,GAAGrC,iBAAiB,CAACoC,WAAW,CAAC,eAAe,EAAEL,OAAO,CAACM,aAAa,CAAC,GAAGjC,QAAQ,CAC1G;EAED,OAAO,OAAO4B,MAAM,CAACM,OAAO,CAACL,OAAO,CAAC,CAAChB,IAAI,CACxCd,MAAM,CAACoC,OAAO,CAACtC,kBAAkB,CAACuC,cAAc,CAACC,OAAO,CAAC,CAAC,EAC1DtC,MAAM,CAACuC,GAAG,CAAEC,IAAI,IAAI;IAClB,MAAMC,IAAI,GAAG,IAAIC,GAAG,EAAe;IACnC,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGH,IAAI,CAACI,KAAK,CAACC,MAAM,EAAEF,CAAC,EAAE,EAAE;MAC1C,MAAMG,GAAG,GAAGN,IAAI,CAACI,KAAK,CAACD,CAAC,CAAC;MACzBF,IAAI,CAACM,GAAG,CAACD,GAAG,CAACE,MAAM,CAACC,KAAK,EAAEH,GAAG,CAAC;IACjC;IACA,OAAOL,IAAI;EACb,CAAC,CAAC,EACFzC,MAAM,CAACkD,aAAa,CAAEC,KAAK,IAAKnD,MAAM,CAACoD,UAAU,CAAC,0CAA0C,EAAED,KAAK,CAAC,CAAC,EACrGnD,MAAM,CAACqD,aAAa,CAAC,YAAY,CAAC,CACnC;AACH,CAAC,CAAC;AAEF;;;;AAIA,OAAO,MAAMC,aAAa,gBAAGtD,MAAM,CAACU,GAAG,CAAC,aAAS;EAC/C,MAAMmB,MAAM,GAAG,OAAOvB,aAAa;EAEnC,OAAON,MAAM,CAAC2B,UAAU,CAAC,WAAU4B,IAAY;IAC7CA,IAAI,GAAG;MACLC,UAAU,EAAE,IAAI;MAChBC,IAAI,EAAE,KAAK;MACXC,QAAQ,EAAE;QACR1B,SAAS,EAAE,SAAS;QACpB,GAAGuB,IAAI,CAACG;OACT;MACD,GAAGH;KACJ;IACD,MAAMvB,SAAS,GAAGuB,IAAI,CAACG,QAAQ,EAAE1B,SAAS,IAAI,SAAS;IACvD,MAAM2B,IAAI,GAAGJ,IAAI,CAACG,QAAS,CAACC,IAAK;IACjC,MAAMC,UAAU,GAAG/D,iBAAiB,CAACkC,GAAG,CAAC,kBAAkBC,SAAS,SAAS2B,IAAI,EAAE,CAAC,CAAC7C,IAAI,CACvFe,MAAM,CAACM,OAAO,CACf;IACD,MAAM0B,OAAO,GAAGD,UAAU,CAAC9C,IAAI,CAC7Bd,MAAM,CAACoC,OAAO,CAACtC,kBAAkB,CAACuC,cAAc,CAACyB,GAAG,CAAC,CAAC,EACtD9D,MAAM,CAAC+D,MAAM,EACb/D,MAAM,CAACgE,KAAK,CAAC;MACXC,KAAK,EAAGC,CAAC,IAAKA,CAAC,CAAChD,IAAI,KAAK,YAAY;MACrCM,QAAQ,EAAEpB,QAAQ,CAACqB,MAAM,CAAC,WAAW;KACtC,CAAC,EACFzB,MAAM,CAACmE,OAAO,CAAEC,GAAG,IAAKA,GAAG,CAAClD,IAAI,KAAK,eAAe,IAAIkD,GAAG,CAACC,QAAQ,CAACrB,MAAM,KAAK,GAAG,EAAE,MAAMhD,MAAM,CAACsE,WAAW,CAAC,EAC9GtE,MAAM,CAACuE,KAAK,CACb;IACD,MAAMC,UAAU,GAAGZ,UAAU,CAAC9C,IAAI,CAChCd,MAAM,CAACyE,EAAE,CAAC,IAAI,CAAC,EACfzE,MAAM,CAACmE,OAAO,CACXC,GAAG,IAAKA,GAAG,CAAClD,IAAI,KAAK,eAAe,IAAIkD,GAAG,CAACC,QAAQ,CAACrB,MAAM,KAAK,GAAG,EACpE,MAAMhD,MAAM,CAAC0E,OAAO,CAAC,KAAK,CAAC,CAC5B,CACF;IACD,MAAMC,SAAS,GAAG9E,iBAAiB,CAAC+E,IAAI,CAAC,kBAAkB5C,SAAS,OAAO,CAAC,CAAClB,IAAI,CAC/EjB,iBAAiB,CAACgF,cAAc,CAACtB,IAAI,CAAC,EACtC1B,MAAM,CAACM,OAAO,EACdnC,MAAM,CAACmE,OAAO,CACXC,GAAG,IAAKA,GAAG,CAAClD,IAAI,KAAK,eAAe,IAAIkD,GAAG,CAACC,QAAQ,CAACrB,MAAM,KAAK,GAAG,EACpE,MAAMa,OAAO,CACd,EACD7D,MAAM,CAACkD,aAAa,CAAClD,MAAM,CAAC8E,OAAO,CAAC,EACpC9E,MAAM,CAACuE,KAAK,CACb;IACD,MAAMQ,SAAS,GAAGlF,iBAAiB,CAACmF,GAAG,CAAC,kBAAkBhD,SAAS,SAAS2B,IAAI,EAAE,CAAC,CAAC7C,IAAI,CACtFe,MAAM,CAACM,OAAO,EACdnC,MAAM,CAACoC,OAAO,CAAE6C,GAAG,IAAKA,GAAG,CAACC,IAAI,CAAC,EACjClF,MAAM,CAACmE,OAAO,CACXC,GAAG,IAAKA,GAAG,CAAClD,IAAI,KAAK,eAAe,IAAIkD,GAAG,CAACC,QAAQ,CAACrB,MAAM,KAAK,GAAG,EACpE,MAAMhD,MAAM,CAACmF,IAAI,CAClB,EACDnF,MAAM,CAACkD,aAAa,CAAClD,MAAM,CAAC8E,OAAO,CAAC,EACpC9E,MAAM,CAACuE,KAAK,EACZvE,MAAM,CAACoF,MAAM,CACd;IACD,OAAOpF,MAAM,CAACqF,YAAY,CAACrF,MAAM,CAAC2B,UAAU,CAAC,aAAS;MACpD,OAAOoD,SAAS;MAChB,OAAOP,UAAU,CAAC1D,IAAI,CACpBd,MAAM,CAACsF,MAAM,CAAC;QACZC,KAAK,EAAGC,KAAK,IAAK,CAACA,KAAK;QACxBhE,QAAQ,EAAEpB,QAAQ,CAACqB,MAAM,CAAC,WAAW;OACtC,CAAC,EACFzB,MAAM,CAACuE,KAAK,CACb;IACH,CAAC,CAAC,CAAC;IAEH,IAAIkB,IAAI,GAAGtF,MAAM,CAACuF,IAAI,EAAO;IAC7B,OAAOvF,MAAM,CAACwF,MAAM,CAACF,IAAI,CAAC,IAAI,CAACA,IAAI,CAACrE,KAAK,CAACwE,OAAO,EAAE;MACjD,IAAIzF,MAAM,CAACwF,MAAM,CAACF,IAAI,CAAC,EAAE;QACvB,OAAOd,SAAS;MAClB;MACA,OAAO3E,MAAM,CAAC6F,KAAK,CAAC,WAAW,CAAC;MAChCJ,IAAI,GAAG,OAAO5B,OAAO;IACvB;IACA,OAAO4B,IAAI,CAACrE,KAAK,CAAC4B,MAAM;EAC1B,CAAC,EAAEhD,MAAM,CAAC8F,QAAQ,CAAC,yBAAyB,CAAC,CAAC;AAChD,CAAC,CAAC;AAEF;;;;AAIA,OAAM,MAAOC,SAAU,sBAAQ1F,MAAM,CAAC2F,KAAK,CAAY,yCAAyC,CAAC,CAAC;EAChGC,KAAK,EAAE5F,MAAM,CAAC6F,MAAM;EACpBC,UAAU,eAAE9F,MAAM,CAAC+F,KAAK,cAAC/F,MAAM,CAACgG,MAAM,CAAC;IACrCC,IAAI,EAAEjG,MAAM,CAAC6F,MAAM;IACnBlD,MAAM,EAAE3C,MAAM,CAAC6F,MAAM;IACrBK,kBAAkB,EAAElG,MAAM,CAAC6F;GAC5B,CAAC,CAAC;EACHjD,KAAK,EAAE5C,MAAM,CAAC6F,MAAM;EACpBM,MAAM,EAAEnG,MAAM,CAAC6F;CAChB,CAAC;AAEF;;;;AAIA,OAAM,MAAOpC,GAAI,sBAAQzD,MAAM,CAAC2F,KAAK,CAAM,mCAAmC,CAAC,CAAC;EAC9EhD,MAAM,EAAE+C;CACT,CAAC;EACA,IAAIH,OAAOA,CAAA;IACT,KAAK,IAAIjD,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAG,IAAI,CAACK,MAAM,CAACmD,UAAU,CAACtD,MAAM,EAAEF,CAAC,EAAE,EAAE;MACtD,MAAM8D,SAAS,GAAG,IAAI,CAACzD,MAAM,CAACmD,UAAU,CAACxD,CAAC,CAAC;MAC3C,IAAI8D,SAAS,CAACH,IAAI,KAAK,OAAO,EAAE;QAC9B,OAAOG,SAAS,CAACzD,MAAM,KAAK,MAAM;MACpC;IACF;IACA,OAAO,KAAK;EACd;EAEA,IAAI0D,qBAAqBA,CAAA;IACvB,IAAIC,aAAiC;IACrC,IAAIC,OAA2B;IAC/B,KAAK,IAAIjE,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAG,IAAI,CAACK,MAAM,CAACmD,UAAU,CAACtD,MAAM,EAAEF,CAAC,EAAE,EAAE;MACtD,MAAM8D,SAAS,GAAG,IAAI,CAACzD,MAAM,CAACmD,UAAU,CAACxD,CAAC,CAAC;MAC3C,QAAQ8D,SAAS,CAACH,IAAI;QACpB,KAAK,aAAa;UAAE;YAClB,IAAIG,SAAS,CAACzD,MAAM,KAAK,MAAM,EAAE;cAC/B,OAAO,IAAI;YACb;YACA2D,aAAa,GAAGF,SAAS,CAACF,kBAAkB;YAC5C;UACF;QACA,KAAK,OAAO;UAAE;YACZ,IAAIE,SAAS,CAACzD,MAAM,KAAK,MAAM,EAAE;cAC/B,OAAO,IAAI;YACb;YACA4D,OAAO,GAAGH,SAAS,CAACF,kBAAkB;YACtC;UACF;MACF;IACF;IACA;IACA;IACA,OAAOI,aAAa,KAAKC,OAAO;EAClC;;AAGF,MAAMtE,OAAO,gBAAGjC,MAAM,CAACgG,MAAM,CAAC;EAC5BzD,KAAK,eAAEvC,MAAM,CAAC+F,KAAK,CAACtC,GAAG;CACxB,CAAC","ignoreList":[]}
|
package/dist/esm/RunnerHealth.js
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @since 1.0.0
|
|
3
3
|
*/
|
|
4
|
-
import * as FileSystem from "@effect/platform/FileSystem";
|
|
5
|
-
import * as HttpClient from "@effect/platform/HttpClient";
|
|
6
|
-
import * as HttpClientRequest from "@effect/platform/HttpClientRequest";
|
|
7
|
-
import * as HttpClientResponse from "@effect/platform/HttpClientResponse";
|
|
8
4
|
import * as Context from "effect/Context";
|
|
9
5
|
import * as Effect from "effect/Effect";
|
|
10
|
-
import { identity } from "effect/Function";
|
|
11
6
|
import * as Layer from "effect/Layer";
|
|
12
7
|
import * as Schedule from "effect/Schedule";
|
|
13
|
-
import * as
|
|
8
|
+
import * as K8s from "./K8sHttpClient.js";
|
|
14
9
|
import * as Runners from "./Runners.js";
|
|
15
10
|
/**
|
|
16
11
|
* Represents the service used to check if a Runner is healthy.
|
|
@@ -63,66 +58,11 @@ export const layerPing = /*#__PURE__*/Layer.scoped(RunnerHealth, makePing);
|
|
|
63
58
|
* @category Constructors
|
|
64
59
|
*/
|
|
65
60
|
export const makeK8s = /*#__PURE__*/Effect.fnUntraced(function* (options) {
|
|
66
|
-
const
|
|
67
|
-
const token = yield* fs.readFileString("/var/run/secrets/kubernetes.io/serviceaccount/token").pipe(Effect.option);
|
|
68
|
-
const client = (yield* HttpClient.HttpClient).pipe(HttpClient.filterStatusOk);
|
|
69
|
-
const baseRequest = HttpClientRequest.get("https://kubernetes.default.svc/api").pipe(token._tag === "Some" ? HttpClientRequest.bearerToken(token.value.trim()) : identity);
|
|
70
|
-
const getPods = baseRequest.pipe(HttpClientRequest.appendUrl(options?.namespace ? `/v1/namespaces/${options.namespace}/pods` : "/v1/pods"), HttpClientRequest.setUrlParam("fieldSelector", "status.phase=Running"), options?.labelSelector ? HttpClientRequest.setUrlParam("labelSelector", options.labelSelector) : identity);
|
|
71
|
-
const allPods = yield* client.execute(getPods).pipe(Effect.flatMap(HttpClientResponse.schemaBodyJson(PodList)), Effect.map(list => {
|
|
72
|
-
const pods = new Map();
|
|
73
|
-
for (let i = 0; i < list.items.length; i++) {
|
|
74
|
-
const pod = list.items[i];
|
|
75
|
-
pods.set(pod.status.podIP, pod);
|
|
76
|
-
}
|
|
77
|
-
return pods;
|
|
78
|
-
}), Effect.tapErrorCause(cause => Effect.logWarning("Failed to fetch pods from Kubernetes API", cause)), Effect.cachedWithTTL("10 seconds"));
|
|
61
|
+
const allPods = yield* K8s.makeGetPods(options);
|
|
79
62
|
return RunnerHealth.of({
|
|
80
|
-
isAlive: address => allPods.pipe(Effect.map(pods => pods.get(address.host)?.
|
|
63
|
+
isAlive: address => allPods.pipe(Effect.map(pods => pods.get(address.host)?.isReadyOrInitializing ?? false), Effect.catchAllCause(() => Effect.succeed(true)))
|
|
81
64
|
});
|
|
82
65
|
});
|
|
83
|
-
class Pod extends /*#__PURE__*/Schema.Class("effect/cluster/RunnerHealth/Pod")({
|
|
84
|
-
status: /*#__PURE__*/Schema.Struct({
|
|
85
|
-
phase: Schema.String,
|
|
86
|
-
conditions: /*#__PURE__*/Schema.Array(/*#__PURE__*/Schema.Struct({
|
|
87
|
-
type: Schema.String,
|
|
88
|
-
status: Schema.String,
|
|
89
|
-
lastTransitionTime: Schema.String
|
|
90
|
-
})),
|
|
91
|
-
podIP: Schema.String
|
|
92
|
-
})
|
|
93
|
-
}) {
|
|
94
|
-
get isReady() {
|
|
95
|
-
let initializedAt;
|
|
96
|
-
let readyAt;
|
|
97
|
-
for (let i = 0; i < this.status.conditions.length; i++) {
|
|
98
|
-
const condition = this.status.conditions[i];
|
|
99
|
-
switch (condition.type) {
|
|
100
|
-
case "Initialized":
|
|
101
|
-
{
|
|
102
|
-
if (condition.status !== "True") {
|
|
103
|
-
return true;
|
|
104
|
-
}
|
|
105
|
-
initializedAt = condition.lastTransitionTime;
|
|
106
|
-
break;
|
|
107
|
-
}
|
|
108
|
-
case "Ready":
|
|
109
|
-
{
|
|
110
|
-
if (condition.status === "True") {
|
|
111
|
-
return true;
|
|
112
|
-
}
|
|
113
|
-
readyAt = condition.lastTransitionTime;
|
|
114
|
-
break;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
// if the pod is still booting up, consider it ready as it would have
|
|
119
|
-
// already registered itself with RunnerStorage by now
|
|
120
|
-
return initializedAt === readyAt;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
const PodList = /*#__PURE__*/Schema.Struct({
|
|
124
|
-
items: /*#__PURE__*/Schema.Array(Pod)
|
|
125
|
-
});
|
|
126
66
|
/**
|
|
127
67
|
* A layer which will check the Kubernetes API to see if a Runner is healthy.
|
|
128
68
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RunnerHealth.js","names":["
|
|
1
|
+
{"version":3,"file":"RunnerHealth.js","names":["Context","Effect","Layer","Schedule","K8s","Runners","RunnerHealth","Tag","layerNoop","succeed","isAlive","makePing","gen","runners","schedule","spaced","address","ping","pipe","timeout","retry","times","isSuccess","of","layerPing","scoped","makeK8s","fnUntraced","options","allPods","makeGetPods","map","pods","get","host","isReadyOrInitializing","catchAllCause","layerK8s","effect"],"sources":["../../src/RunnerHealth.ts"],"sourcesContent":[null],"mappings":"AAAA;;;AAGA,OAAO,KAAKA,OAAO,MAAM,gBAAgB;AACzC,OAAO,KAAKC,MAAM,MAAM,eAAe;AACvC,OAAO,KAAKC,KAAK,MAAM,cAAc;AACrC,OAAO,KAAKC,QAAQ,MAAM,iBAAiB;AAE3C,OAAO,KAAKC,GAAG,MAAM,oBAAoB;AAEzC,OAAO,KAAKC,OAAO,MAAM,cAAc;AAEvC;;;;;;;;;;AAUA,OAAM,MAAOC,YAAa,sBAAQN,OAAO,CAACO,GAAG,CAAC,8BAA8B,CAAC,EAK1E;AAEH;;;;;;;;AAQA,OAAO,MAAMC,SAAS,gBAAGN,KAAK,CAACO,OAAO,CAACH,YAAY,EAAE;EACnDI,OAAO,EAAEA,CAAA,KAAMT,MAAM,CAACQ,OAAO,CAAC,IAAI;CACnC,CAAC;AAEF;;;;AAIA,OAAO,MAAME,QAAQ,gBAIjBV,MAAM,CAACW,GAAG,CAAC,aAAS;EACtB,MAAMC,OAAO,GAAG,OAAOR,OAAO,CAACA,OAAO;EACtC,MAAMS,QAAQ,GAAGX,QAAQ,CAACY,MAAM,CAAC,GAAG,CAAC;EAErC,SAASL,OAAOA,CAACM,OAAsB;IACrC,OAAOH,OAAO,CAACI,IAAI,CAACD,OAAO,CAAC,CAACE,IAAI,CAC/BjB,MAAM,CAACkB,OAAO,CAAC,MAAM,CAAC,EACtBlB,MAAM,CAACmB,KAAK,CAAC;MAAEC,KAAK,EAAE,CAAC;MAAEP;IAAQ,CAAE,CAAC,EACpCb,MAAM,CAACqB,SAAS,CACjB;EACH;EAEA,OAAOhB,YAAY,CAACiB,EAAE,CAAC;IAAEb;EAAO,CAAE,CAAC;AACrC,CAAC,CAAC;AAEF;;;;;;AAMA,OAAO,MAAMc,SAAS,gBAIlBtB,KAAK,CAACuB,MAAM,CAACnB,YAAY,EAAEK,QAAQ,CAAC;AAExC;;;;AAIA,OAAO,MAAMe,OAAO,gBAAGzB,MAAM,CAAC0B,UAAU,CAAC,WAAUC,OAGlD;EACC,MAAMC,OAAO,GAAG,OAAOzB,GAAG,CAAC0B,WAAW,CAACF,OAAO,CAAC;EAE/C,OAAOtB,YAAY,CAACiB,EAAE,CAAC;IACrBb,OAAO,EAAGM,OAAO,IACfa,OAAO,CAACX,IAAI,CACVjB,MAAM,CAAC8B,GAAG,CAAEC,IAAI,IAAKA,IAAI,CAACC,GAAG,CAACjB,OAAO,CAACkB,IAAI,CAAC,EAAEC,qBAAqB,IAAI,KAAK,CAAC,EAC5ElC,MAAM,CAACmC,aAAa,CAAC,MAAMnC,MAAM,CAACQ,OAAO,CAAC,IAAI,CAAC,CAAC;GAErD,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;;;;;;;;AAYA,OAAO,MAAM4B,QAAQ,GACnBT,OAGa,IAKV1B,KAAK,CAACoC,MAAM,CAAChC,YAAY,EAAEoB,OAAO,CAACE,OAAO,CAAC,CAAC","ignoreList":[]}
|
package/dist/esm/index.js
CHANGED
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["ClusterCron","ClusterError","ClusterMetrics","ClusterSchema","ClusterWorkflowEngine","DeliverAt","Entity","EntityAddress","EntityId","EntityProxy","EntityProxyServer","EntityResource","EntityType","Envelope","HttpRunner","MachineId","Message","MessageStorage","Reply","Runner","RunnerAddress","RunnerHealth","RunnerServer","RunnerStorage","Runners","ShardId","Sharding","ShardingConfig","ShardingRegistrationEvent","Singleton","SingletonAddress","Snowflake","SocketRunner","SqlMessageStorage","SqlRunnerStorage"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA;;;AAGA,OAAO,KAAKA,WAAW,MAAM,kBAAkB;AAE/C;;;AAGA,OAAO,KAAKC,YAAY,MAAM,mBAAmB;AAEjD;;;AAGA,OAAO,KAAKC,cAAc,MAAM,qBAAqB;AAErD;;;AAGA,OAAO,KAAKC,aAAa,MAAM,oBAAoB;AAEnD;;;AAGA,OAAO,KAAKC,qBAAqB,MAAM,4BAA4B;AAEnE;;;AAGA,OAAO,KAAKC,SAAS,MAAM,gBAAgB;AAE3C;;;AAGA,OAAO,KAAKC,MAAM,MAAM,aAAa;AAErC;;;AAGA,OAAO,KAAKC,aAAa,MAAM,oBAAoB;AAEnD;;;AAGA,OAAO,KAAKC,QAAQ,MAAM,eAAe;AAEzC;;;AAGA,OAAO,KAAKC,WAAW,MAAM,kBAAkB;AAE/C;;;AAGA,OAAO,KAAKC,iBAAiB,MAAM,wBAAwB;AAE3D;;;AAGA,OAAO,KAAKC,cAAc,MAAM,qBAAqB;AAErD;;;AAGA,OAAO,KAAKC,UAAU,MAAM,iBAAiB;AAE7C;;;AAGA,OAAO,KAAKC,QAAQ,MAAM,eAAe;AAEzC;;;AAGA,OAAO,KAAKC,UAAU,MAAM,iBAAiB;AAE7C;;;AAGA,OAAO,KAAKC,SAAS,MAAM,gBAAgB;AAE3C;;;AAGA,OAAO,KAAKC,OAAO,MAAM,cAAc;AAEvC;;;AAGA,OAAO,KAAKC,cAAc,MAAM,qBAAqB;AAErD;;;AAGA,OAAO,KAAKC,KAAK,MAAM,YAAY;AAEnC;;;AAGA,OAAO,KAAKC,MAAM,MAAM,aAAa;AAErC;;;AAGA,OAAO,KAAKC,aAAa,MAAM,oBAAoB;AAEnD;;;AAGA,OAAO,KAAKC,YAAY,MAAM,mBAAmB;AAEjD;;;AAGA,OAAO,KAAKC,YAAY,MAAM,mBAAmB;AAEjD;;;AAGA,OAAO,KAAKC,aAAa,MAAM,oBAAoB;AAEnD;;;AAGA,OAAO,KAAKC,OAAO,MAAM,cAAc;AAEvC;;;AAGA,OAAO,KAAKC,OAAO,MAAM,cAAc;AAEvC;;;AAGA,OAAO,KAAKC,QAAQ,MAAM,eAAe;AAEzC;;;AAGA,OAAO,KAAKC,cAAc,MAAM,qBAAqB;AAErD;;;AAGA,OAAO,KAAKC,yBAAyB,MAAM,gCAAgC;AAE3E;;;AAGA,OAAO,KAAKC,SAAS,MAAM,gBAAgB;AAE3C;;;AAGA,OAAO,KAAKC,gBAAgB,MAAM,uBAAuB;AAEzD;;;AAGA,OAAO,KAAKC,SAAS,MAAM,gBAAgB;AAE3C;;;AAGA,OAAO,KAAKC,YAAY,MAAM,mBAAmB;AAEjD;;;AAGA,OAAO,KAAKC,iBAAiB,MAAM,wBAAwB;AAE3D;;;AAGA,OAAO,KAAKC,gBAAgB,MAAM,uBAAuB","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"index.js","names":["ClusterCron","ClusterError","ClusterMetrics","ClusterSchema","ClusterWorkflowEngine","DeliverAt","Entity","EntityAddress","EntityId","EntityProxy","EntityProxyServer","EntityResource","EntityType","Envelope","HttpRunner","K8sHttpClient","MachineId","Message","MessageStorage","Reply","Runner","RunnerAddress","RunnerHealth","RunnerServer","RunnerStorage","Runners","ShardId","Sharding","ShardingConfig","ShardingRegistrationEvent","Singleton","SingletonAddress","Snowflake","SocketRunner","SqlMessageStorage","SqlRunnerStorage"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA;;;AAGA,OAAO,KAAKA,WAAW,MAAM,kBAAkB;AAE/C;;;AAGA,OAAO,KAAKC,YAAY,MAAM,mBAAmB;AAEjD;;;AAGA,OAAO,KAAKC,cAAc,MAAM,qBAAqB;AAErD;;;AAGA,OAAO,KAAKC,aAAa,MAAM,oBAAoB;AAEnD;;;AAGA,OAAO,KAAKC,qBAAqB,MAAM,4BAA4B;AAEnE;;;AAGA,OAAO,KAAKC,SAAS,MAAM,gBAAgB;AAE3C;;;AAGA,OAAO,KAAKC,MAAM,MAAM,aAAa;AAErC;;;AAGA,OAAO,KAAKC,aAAa,MAAM,oBAAoB;AAEnD;;;AAGA,OAAO,KAAKC,QAAQ,MAAM,eAAe;AAEzC;;;AAGA,OAAO,KAAKC,WAAW,MAAM,kBAAkB;AAE/C;;;AAGA,OAAO,KAAKC,iBAAiB,MAAM,wBAAwB;AAE3D;;;AAGA,OAAO,KAAKC,cAAc,MAAM,qBAAqB;AAErD;;;AAGA,OAAO,KAAKC,UAAU,MAAM,iBAAiB;AAE7C;;;AAGA,OAAO,KAAKC,QAAQ,MAAM,eAAe;AAEzC;;;AAGA,OAAO,KAAKC,UAAU,MAAM,iBAAiB;AAE7C;;;AAGA,OAAO,KAAKC,aAAa,MAAM,oBAAoB;AAEnD;;;AAGA,OAAO,KAAKC,SAAS,MAAM,gBAAgB;AAE3C;;;AAGA,OAAO,KAAKC,OAAO,MAAM,cAAc;AAEvC;;;AAGA,OAAO,KAAKC,cAAc,MAAM,qBAAqB;AAErD;;;AAGA,OAAO,KAAKC,KAAK,MAAM,YAAY;AAEnC;;;AAGA,OAAO,KAAKC,MAAM,MAAM,aAAa;AAErC;;;AAGA,OAAO,KAAKC,aAAa,MAAM,oBAAoB;AAEnD;;;AAGA,OAAO,KAAKC,YAAY,MAAM,mBAAmB;AAEjD;;;AAGA,OAAO,KAAKC,YAAY,MAAM,mBAAmB;AAEjD;;;AAGA,OAAO,KAAKC,aAAa,MAAM,oBAAoB;AAEnD;;;AAGA,OAAO,KAAKC,OAAO,MAAM,cAAc;AAEvC;;;AAGA,OAAO,KAAKC,OAAO,MAAM,cAAc;AAEvC;;;AAGA,OAAO,KAAKC,QAAQ,MAAM,eAAe;AAEzC;;;AAGA,OAAO,KAAKC,cAAc,MAAM,qBAAqB;AAErD;;;AAGA,OAAO,KAAKC,yBAAyB,MAAM,gCAAgC;AAE3E;;;AAGA,OAAO,KAAKC,SAAS,MAAM,gBAAgB;AAE3C;;;AAGA,OAAO,KAAKC,gBAAgB,MAAM,uBAAuB;AAEzD;;;AAGA,OAAO,KAAKC,SAAS,MAAM,gBAAgB;AAE3C;;;AAGA,OAAO,KAAKC,YAAY,MAAM,mBAAmB;AAEjD;;;AAGA,OAAO,KAAKC,iBAAiB,MAAM,wBAAwB;AAE3D;;;AAGA,OAAO,KAAKC,gBAAgB,MAAM,uBAAuB","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect/cluster",
|
|
3
|
-
"version": "0.53.
|
|
3
|
+
"version": "0.53.4",
|
|
4
4
|
"description": "Unified interfaces for common cluster-specific services",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
},
|
|
11
11
|
"sideEffects": [],
|
|
12
12
|
"homepage": "https://effect.website",
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"kubernetes-types": "^1.30.0"
|
|
15
|
+
},
|
|
13
16
|
"peerDependencies": {
|
|
14
17
|
"@effect/platform": "^0.93.3",
|
|
15
18
|
"@effect/sql": "^0.48.0",
|
|
@@ -105,6 +108,11 @@
|
|
|
105
108
|
"import": "./dist/esm/HttpRunner.js",
|
|
106
109
|
"default": "./dist/cjs/HttpRunner.js"
|
|
107
110
|
},
|
|
111
|
+
"./K8sHttpClient": {
|
|
112
|
+
"types": "./dist/dts/K8sHttpClient.d.ts",
|
|
113
|
+
"import": "./dist/esm/K8sHttpClient.js",
|
|
114
|
+
"default": "./dist/cjs/K8sHttpClient.js"
|
|
115
|
+
},
|
|
108
116
|
"./MachineId": {
|
|
109
117
|
"types": "./dist/dts/MachineId.d.ts",
|
|
110
118
|
"import": "./dist/esm/MachineId.js",
|
|
@@ -258,6 +266,9 @@
|
|
|
258
266
|
"HttpRunner": [
|
|
259
267
|
"./dist/dts/HttpRunner.d.ts"
|
|
260
268
|
],
|
|
269
|
+
"K8sHttpClient": [
|
|
270
|
+
"./dist/dts/K8sHttpClient.d.ts"
|
|
271
|
+
],
|
|
261
272
|
"MachineId": [
|
|
262
273
|
"./dist/dts/MachineId.d.ts"
|
|
263
274
|
],
|
package/src/EntityResource.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @since 1.0.0
|
|
3
3
|
*/
|
|
4
|
+
import * as Context from "effect/Context"
|
|
4
5
|
import * as Duration from "effect/Duration"
|
|
5
6
|
import * as Effect from "effect/Effect"
|
|
6
7
|
import { identity } from "effect/Function"
|
|
7
8
|
import * as RcRef from "effect/RcRef"
|
|
8
9
|
import * as Scope from "effect/Scope"
|
|
10
|
+
import type * as v1 from "kubernetes-types/core/v1.d.ts"
|
|
9
11
|
import * as Entity from "./Entity.js"
|
|
12
|
+
import * as K8sHttpClient from "./K8sHttpClient.js"
|
|
10
13
|
import type { Sharding } from "./Sharding.js"
|
|
11
14
|
|
|
12
15
|
/**
|
|
@@ -31,6 +34,19 @@ export interface EntityResource<out A, out E = never> {
|
|
|
31
34
|
readonly close: Effect.Effect<void>
|
|
32
35
|
}
|
|
33
36
|
|
|
37
|
+
/**
|
|
38
|
+
* A `Scope` that is only closed when the resource is explicitly closed.
|
|
39
|
+
*
|
|
40
|
+
* It is not closed during restarts, due to shard movement or node shutdowns.
|
|
41
|
+
*
|
|
42
|
+
* @since 1.0.0
|
|
43
|
+
* @category Scope
|
|
44
|
+
*/
|
|
45
|
+
export class CloseScope extends Context.Tag("@effect/cluster/EntityResource/CloseScope")<
|
|
46
|
+
CloseScope,
|
|
47
|
+
Scope.Scope
|
|
48
|
+
>() {}
|
|
49
|
+
|
|
34
50
|
/**
|
|
35
51
|
* A `EntityResource` is a resource that can be acquired inside a cluster
|
|
36
52
|
* entity, which will keep the entity alive even across restarts.
|
|
@@ -47,55 +63,32 @@ export interface EntityResource<out A, out E = never> {
|
|
|
47
63
|
export const make: <A, E, R>(options: {
|
|
48
64
|
readonly acquire: Effect.Effect<A, E, R>
|
|
49
65
|
readonly idleTimeToLive?: Duration.DurationInput | undefined
|
|
50
|
-
/**
|
|
51
|
-
* When to close the resource Scope.
|
|
52
|
-
*
|
|
53
|
-
* If set to "explicit", the resource will only be cleaned up when either the
|
|
54
|
-
* `idleTimeToLive` is reached, or the .close effect is called.
|
|
55
|
-
*
|
|
56
|
-
* Defaults to "always", which means the resource will be cleaned up when the
|
|
57
|
-
* the parent Scope is closed.
|
|
58
|
-
*/
|
|
59
|
-
readonly shutdownMode?: "explicit" | "always" | undefined
|
|
60
66
|
}) => Effect.Effect<
|
|
61
67
|
EntityResource<A, E>,
|
|
62
68
|
E,
|
|
63
|
-
Scope.Scope | R | Sharding | Entity.CurrentAddress
|
|
69
|
+
Scope.Scope | Exclude<R, CloseScope> | Sharding | Entity.CurrentAddress
|
|
64
70
|
> = Effect.fnUntraced(function*<A, E, R>(options: {
|
|
65
71
|
readonly acquire: Effect.Effect<A, E, R>
|
|
66
72
|
readonly idleTimeToLive?: Duration.DurationInput | undefined
|
|
67
|
-
readonly shutdownMode?: "explicit" | "always" | undefined
|
|
68
73
|
}) {
|
|
69
|
-
const shutdownMode = options.shutdownMode ?? "always"
|
|
70
74
|
let shuttingDown = false
|
|
71
75
|
|
|
72
76
|
const ref = yield* RcRef.make({
|
|
73
77
|
acquire: Effect.gen(function*() {
|
|
74
|
-
|
|
78
|
+
const closeable = yield* Scope.make()
|
|
75
79
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
Effect.fnUntraced(function*(exit) {
|
|
82
|
-
if (shuttingDown) return
|
|
83
|
-
yield* Scope.close(closeable, exit)
|
|
84
|
-
yield* Entity.keepAlive(false)
|
|
85
|
-
}, Effect.provide(context))
|
|
86
|
-
)
|
|
87
|
-
scope = closeable
|
|
88
|
-
} else {
|
|
89
|
-
yield* Effect.addFinalizer(() => {
|
|
90
|
-
if (shuttingDown) return Effect.void
|
|
91
|
-
return Entity.keepAlive(false)
|
|
80
|
+
yield* Effect.addFinalizer(
|
|
81
|
+
Effect.fnUntraced(function*(exit) {
|
|
82
|
+
if (shuttingDown) return
|
|
83
|
+
yield* Scope.close(closeable, exit)
|
|
84
|
+
yield* Entity.keepAlive(false)
|
|
92
85
|
})
|
|
93
|
-
|
|
86
|
+
)
|
|
94
87
|
|
|
95
88
|
yield* Entity.keepAlive(true)
|
|
96
89
|
|
|
97
90
|
return yield* options.acquire.pipe(
|
|
98
|
-
|
|
91
|
+
Effect.provideService(CloseScope, closeable)
|
|
99
92
|
)
|
|
100
93
|
}),
|
|
101
94
|
idleTimeToLive: options.idleTimeToLive ?? Duration.infinity
|
|
@@ -115,3 +108,31 @@ export const make: <A, E, R>(options: {
|
|
|
115
108
|
close: RcRef.invalidate(ref)
|
|
116
109
|
})
|
|
117
110
|
})
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* @since 1.0.0
|
|
114
|
+
* @category Kubernetes
|
|
115
|
+
*/
|
|
116
|
+
export const makeK8sPod: (
|
|
117
|
+
spec: v1.Pod,
|
|
118
|
+
options?: {
|
|
119
|
+
readonly idleTimeToLive?: Duration.DurationInput | undefined
|
|
120
|
+
} | undefined
|
|
121
|
+
) => Effect.Effect<
|
|
122
|
+
EntityResource<K8sHttpClient.PodStatus>,
|
|
123
|
+
never,
|
|
124
|
+
Scope.Scope | Sharding | Entity.CurrentAddress | K8sHttpClient.K8sHttpClient
|
|
125
|
+
> = Effect.fnUntraced(function*(spec: v1.Pod, options?: {
|
|
126
|
+
readonly idleTimeToLive?: Duration.DurationInput | undefined
|
|
127
|
+
}) {
|
|
128
|
+
const createPod = yield* K8sHttpClient.makeCreatePod
|
|
129
|
+
return yield* make({
|
|
130
|
+
...options,
|
|
131
|
+
acquire: Effect.gen(function*() {
|
|
132
|
+
const scope = yield* CloseScope
|
|
133
|
+
return yield* createPod(spec).pipe(
|
|
134
|
+
Scope.extend(scope)
|
|
135
|
+
)
|
|
136
|
+
})
|
|
137
|
+
})
|
|
138
|
+
})
|