Skip to content

Commit b22b15a

Browse files
committed
start working on getting the client up and running
Signed-off-by: Robert Landers <landers.robert@gmail.com>
1 parent cd054a7 commit b22b15a

13 files changed

Lines changed: 269 additions & 55 deletions

File tree

.idea/codeStyles/Project.xml

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cli/Makefile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ endif
1212

1313
LOCAL_MODULE := /home/withinboredom/code/durable-php/cli
1414
GEN_STUB := /home/withinboredom/code/php-src/build/gen_stub.php
15-
LOCAL_FRANKENPHP := /home/withinboredom/code/frankenphp/caddy
15+
LOCAL_FRANKENPHP_CADDY := /home/withinboredom/code/frankenphp/caddy
16+
LOCAL_FRANKENPHP := /home/withinboredom/code/frankenphp
1617

1718
# Targets
1819
frankenphp: ext/build/ext.go ext/build/ext_arginfo.h
@@ -22,7 +23,8 @@ frankenphp: ext/build/ext.go ext/build/ext_arginfo.h
2223
CGO_LDFLAGS="$(PHP_LDFLAGS) $(PHP_LIBS)" \
2324
xcaddy build \
2425
--output frankenphp \
25-
--with github.com/dunglas/frankenphp/caddy=$(LOCAL_FRANKENPHP) \
26+
--with github.com/dunglas/frankenphp/caddy=$(LOCAL_FRANKENPHP_CADDY) \
27+
--with github.com/dunglas/frankenphp=$(LOCAL_FRANKENPHP) \
2628
--with github.com/bottledcode/durable-php/cli=$(LOCAL_MODULE)
2729

2830
ext/build/ext_arginfo.h: ext/build/ext.stub.php

cli/ext/build/ext.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ void init_object_handlers() {
5757
}
5858

5959
static zend_class_entry *Worker_ce = NULL;
60+
static ext_object *current_worker = NULL;
6061

6162
PHP_METHOD(Bottledcode_DurablePhp_Ext_Worker, __construct) {
6263
ZEND_PARSE_PARAMETERS_NONE();
@@ -227,6 +228,16 @@ PHP_METHOD(Bottledcode_DurablePhp_Ext_Worker, delete) {
227228
delete_wrapper(intern->go_handle);
228229
}
229230

231+
PHP_METHOD(Bottledcode_DurablePhp_Ext_Worker, GetCurrent) {
232+
ZEND_PARSE_PARAMETERS_NONE();
233+
234+
if (current_worker == NULL) {
235+
RETURN_NULL();
236+
}
237+
238+
RETURN_OBJ_COPY(&current_worker->std);
239+
}
240+
230241
void register_all_classes() {
231242
init_object_handlers();
232243
Worker_ce = register_class_Bottledcode_DurablePhp_Ext_Worker();
@@ -237,6 +248,33 @@ void register_all_classes() {
237248
Worker_ce->create_object = ext_create_object;
238249
}
239250

251+
/* Function to set the current worker from Go */
252+
void set_current_worker_handle(uintptr_t handle) {
253+
if (current_worker != NULL) {
254+
/* Release previous worker */
255+
zend_object_release(&current_worker->std);
256+
current_worker = NULL;
257+
}
258+
259+
if (handle != 0) {
260+
/* Create a new Worker object and set its handle */
261+
zend_object *obj = ext_create_object(Worker_ce);
262+
current_worker = ext_object_from_obj(obj);
263+
current_worker->go_handle = handle;
264+
265+
/* Add ref to keep it alive */
266+
GC_ADDREF(&current_worker->std);
267+
}
268+
}
269+
270+
/* Function to clear current worker */
271+
void clear_current_worker() {
272+
if (current_worker != NULL) {
273+
zend_object_release(&current_worker->std);
274+
current_worker = NULL;
275+
}
276+
}
277+
240278
PHP_MINIT_FUNCTION(ext) {
241279
register_all_classes();
242280

cli/ext/build/ext.go

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ package build
33
/*
44
#include <stdlib.h>
55
#include "ext.h"
6+
7+
void set_current_worker_handle(uintptr_t handle);
8+
void clear_current_worker(void);
69
*/
710
import "C"
811
import (
@@ -31,19 +34,22 @@ import "github.com/nats-io/nats.go/jetstream"
3134
import "go.uber.org/zap"
3235

3336
type worker struct {
37+
requestChan chan *frankenphp.WorkerRequest
3438
}
3539

40+
var globalWorkerInstance *worker
41+
3642
func (w *worker) Name() string {
3743
return "m#durable-php"
3844
}
3945

4046
func (w *worker) FileName() string {
4147
// check if target exists
42-
if _, err := os.Stat("src/glue/worker.php"); !os.IsNotExist(err) {
43-
return "src/glue/worker.php"
48+
if _, err := os.Stat("src/Glue/worker.php"); !os.IsNotExist(err) {
49+
return "src/Glue/worker.php"
4450
}
4551

46-
return "vendor/bottledcode/durable-php/src/glue/worker.php"
52+
return "vendor/bottledcode/durable-php/src/Glue/worker.php"
4753
}
4854

4955
func (w *worker) Env() frankenphp.PreparedEnv {
@@ -64,14 +70,18 @@ func (w *worker) ThreadDeactivatedNotification(threadId int) {
6470
}
6571

6672
func (w *worker) ProvideRequest() *frankenphp.WorkerRequest {
67-
return nil
73+
req := <-w.requestChan
74+
return req
6875
}
6976

7077
func init() {
7178
frankenphp.RegisterExtension(unsafe.Pointer(&C.ext_module_entry))
7279

7380
// initialize the workers
74-
frankenphp.RegisterExternalWorker(&worker{})
81+
globalWorkerInstance = &worker{
82+
requestChan: make(chan *frankenphp.WorkerRequest, 100), // Buffer for 100 requests
83+
}
84+
frankenphp.RegisterExternalWorker(globalWorkerInstance)
7585
}
7686

7787
func Authorize(ctx context.Context, ev *glue.EventMessage, from *ids.StateId, preventCreation bool, operation auth.Operation) (bool, error) {
@@ -825,3 +835,41 @@ func delete_wrapper(handle C.uintptr_t) {
825835
structObj := obj.(*Worker)
826836
structObj.delete()
827837
}
838+
839+
// SetCurrentWorker sets the current worker context for the PHP extension
840+
func SetCurrentWorker(worker *Worker) {
841+
if worker == nil {
842+
C.clear_current_worker()
843+
return
844+
}
845+
846+
handle := registerGoObject(worker)
847+
C.set_current_worker_handle(C.uintptr_t(handle))
848+
}
849+
850+
// ClearCurrentWorker clears the current worker context
851+
func ClearCurrentWorker() {
852+
C.clear_current_worker()
853+
}
854+
855+
// GetWorkerInstance returns the global worker instance for feeding requests
856+
func GetWorkerInstance() *worker {
857+
return globalWorkerInstance
858+
}
859+
860+
// InjectWorkerRequest sends a request to the worker for processing
861+
func InjectWorkerRequest(req *frankenphp.WorkerRequest) {
862+
if globalWorkerInstance != nil {
863+
globalWorkerInstance.requestChan <- req
864+
}
865+
}
866+
867+
// StartWorkerConsumer starts a NATS consumer that feeds requests to the worker channel
868+
func StartWorkerConsumer(ctx context.Context, cfg *config.Config, logger *zap.Logger) {
869+
// This will create NATS consumers and convert messages to HTTP requests for the worker
870+
// Instead of using the old lib/consumer.go approach, we create consumers here
871+
// and feed HTTP requests directly to the worker channel
872+
873+
logger.Info("Starting worker-based consumer")
874+
// TODO: Implement NATS consumer logic here
875+
}

cli/ext/build/ext.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
extern zend_module_entry ext_module_entry;
88

9-
9+
/* Functions for managing current worker */
10+
void set_current_worker_handle(uintptr_t handle);
11+
void clear_current_worker(void);
1012

1113
#endif

cli/ext/build/ext.stub.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ class Worker {
1010

1111
public function __construct() {}
1212

13+
public static function GetCurrent(): ?Worker {}
14+
1315
public function startEventLoop(string $kind): void {}
1416

1517
public function drainEventLoop(): void {}

cli/ext/build/ext_arginfo.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 2033dbbdb5b447b9b6e5f1eb6f7b7758b95b40cc */
2+
* Stub hash: 60118ea78de15908a849b87c3010bbd972e60e71 */
33

44
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_Bottledcode_DurablePhp_Ext_emit_event, 0, 3, IS_LONG, 0)
55
ZEND_ARG_TYPE_INFO(0, userContext, IS_ARRAY, 1)
@@ -10,6 +10,9 @@ ZEND_END_ARG_INFO()
1010
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Bottledcode_DurablePhp_Ext_Worker___construct, 0, 0, 0)
1111
ZEND_END_ARG_INFO()
1212

13+
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Bottledcode_DurablePhp_Ext_Worker_GetCurrent, 0, 0, Bottledcode\\DurablePhp\\Ext\\Worker, 1)
14+
ZEND_END_ARG_INFO()
15+
1316
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Bottledcode_DurablePhp_Ext_Worker_startEventLoop, 0, 1, IS_VOID, 0)
1417
ZEND_ARG_TYPE_INFO(0, kind, IS_STRING, 0)
1518
ZEND_END_ARG_INFO()
@@ -50,6 +53,7 @@ ZEND_END_ARG_INFO()
5053

5154
ZEND_FUNCTION(Bottledcode_DurablePhp_Ext_emit_event);
5255
ZEND_METHOD(Bottledcode_DurablePhp_Ext_Worker, __construct);
56+
ZEND_METHOD(Bottledcode_DurablePhp_Ext_Worker, GetCurrent);
5357
ZEND_METHOD(Bottledcode_DurablePhp_Ext_Worker, startEventLoop);
5458
ZEND_METHOD(Bottledcode_DurablePhp_Ext_Worker, drainEventLoop);
5559
ZEND_METHOD(Bottledcode_DurablePhp_Ext_Worker, __destruct);
@@ -71,6 +75,7 @@ static const zend_function_entry ext_functions[] = {
7175

7276
static const zend_function_entry class_Bottledcode_DurablePhp_Ext_Worker_methods[] = {
7377
ZEND_ME(Bottledcode_DurablePhp_Ext_Worker, __construct, arginfo_class_Bottledcode_DurablePhp_Ext_Worker___construct, ZEND_ACC_PUBLIC)
78+
ZEND_ME(Bottledcode_DurablePhp_Ext_Worker, GetCurrent, arginfo_class_Bottledcode_DurablePhp_Ext_Worker_GetCurrent, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
7479
ZEND_ME(Bottledcode_DurablePhp_Ext_Worker, startEventLoop, arginfo_class_Bottledcode_DurablePhp_Ext_Worker_startEventLoop, ZEND_ACC_PUBLIC)
7580
ZEND_ME(Bottledcode_DurablePhp_Ext_Worker, drainEventLoop, arginfo_class_Bottledcode_DurablePhp_Ext_Worker_drainEventLoop, ZEND_ACC_PUBLIC)
7681
ZEND_ME(Bottledcode_DurablePhp_Ext_Worker, __destruct, arginfo_class_Bottledcode_DurablePhp_Ext_Worker___destruct, ZEND_ACC_PUBLIC)

cli/lib/consumer.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,3 +643,4 @@ func processMsg(ctx context.Context, logger *zap.Logger, msg jetstream.Msg, js j
643643

644644
return nil
645645
}
646+

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
"ramsey/uuid": "^4.9.0",
4141
"webonyx/graphql-php": "^15.22.0",
4242
"withinboredom/records": "^0.1.3",
43-
"withinboredom/time": "^6.0.0"
43+
"withinboredom/time": "^6.0.0",
44+
"ext-frankenphp": "*"
4445
},
4546
"require-dev": {
4647
"laravel/pint": "^1.24.0",

src/DurableClient.php

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
use Amp\Http\Client\HttpClientBuilder;
2828
use Bottledcode\DurablePhp\Events\Shares\Operation;
29+
use Bottledcode\DurablePhp\Glue\Provenance;
2930
use Bottledcode\DurablePhp\Search\EntityFilter;
3031
use Bottledcode\DurablePhp\State\EntityId;
3132
use Bottledcode\DurablePhp\State\EntityState;
@@ -43,7 +44,44 @@ public function __construct(
4344
private OrchestrationClientInterface $orchestrationClient,
4445
) {}
4546

46-
public static function get(string $apiHost = 'http://localhost:8080'): self
47+
public static function get(string $apiHost = 'http://localhost:8080', ?Provenance $userContext = null): self
48+
{
49+
if (function_exists('Bottledcode\DurablePhp\Ext\emit_event')) {
50+
$entityClient = new LocalEntityClient();
51+
$orchestrationClient = new LocalOrchestrationClient();
52+
53+
if ($userContext !== null) {
54+
$entityClient->setUserContext($userContext);
55+
$orchestrationClient->setUserContext($userContext);
56+
}
57+
58+
return new self($entityClient, $orchestrationClient);
59+
}
60+
61+
$builder = new HttpClientBuilder();
62+
$builder->retry(3);
63+
64+
$httpClient = $builder->build();
65+
$entityClient = new RemoteEntityClient($apiHost, $httpClient);
66+
$orchestrationClient = new RemoteOrchestrationClient($apiHost, $httpClient);
67+
68+
return new self($entityClient, $orchestrationClient);
69+
}
70+
71+
public static function local(?Provenance $userContext = null): self
72+
{
73+
$entityClient = new LocalEntityClient();
74+
$orchestrationClient = new LocalOrchestrationClient();
75+
76+
if ($userContext !== null) {
77+
$entityClient->setUserContext($userContext);
78+
$orchestrationClient->setUserContext($userContext);
79+
}
80+
81+
return new self($entityClient, $orchestrationClient);
82+
}
83+
84+
public static function remote(string $apiHost = 'http://localhost:8080'): self
4785
{
4886
$builder = new HttpClientBuilder();
4987
$builder->retry(3);

0 commit comments

Comments
 (0)