Skip to content

Commit 02195fd

Browse files
committed

File tree

6 files changed

+120
-105
lines changed

6 files changed

+120
-105
lines changed

polycode/apiserver.go

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,25 +29,52 @@ func invokeHealthCheck(c *gin.Context) {
2929
func invokeApiHandler(c *gin.Context) {
3030
log.Println("client: api request received")
3131
var input ApiStartEvent
32+
3233
if err := c.ShouldBindJSON(&input); err != nil {
33-
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
34-
return
35-
}
34+
errorOutput := ErrorEvent{
35+
Error: ErrInternal.Wrap(err),
36+
}
3637

37-
output := runApi(c, input)
38-
log.Println("client: api request completed")
39-
c.JSON(http.StatusOK, output)
38+
c.JSON(http.StatusInternalServerError, errorOutput)
39+
log.Println("client: api request error")
40+
} else {
41+
output, err := runApi(c, input)
42+
if err != nil {
43+
errorOutput := ErrorEvent{
44+
Error: ErrInternal.Wrap(err),
45+
}
46+
47+
c.JSON(http.StatusInternalServerError, errorOutput)
48+
log.Println("client: api request error")
49+
} else {
50+
c.JSON(http.StatusOK, output)
51+
log.Println("client: api request completed")
52+
}
53+
}
4054
}
4155

4256
func invokeServiceHandler(c *gin.Context) {
4357
log.Println("client: service request received")
44-
var input TaskStartEvent
58+
var input ServiceStartEvent
4559
if err := c.ShouldBindJSON(&input); err != nil {
46-
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
47-
return
48-
}
60+
errorOutput := ErrorEvent{
61+
Error: ErrInternal.Wrap(err),
62+
}
63+
64+
c.JSON(http.StatusInternalServerError, errorOutput)
65+
log.Println("client: service request error")
66+
} else {
67+
output, err := runService(c, input)
68+
if err != nil {
69+
errorOutput := ErrorEvent{
70+
Error: ErrInternal.Wrap(err),
71+
}
4972

50-
output := runTask(c, input)
51-
log.Println("client: service request completed")
52-
c.JSON(http.StatusOK, output)
73+
c.JSON(http.StatusInternalServerError, errorOutput)
74+
log.Println("client: service request error")
75+
} else {
76+
c.JSON(http.StatusOK, output)
77+
log.Println("client: service request completed")
78+
}
79+
}
5380
}

polycode/client.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,14 @@ type ExecServiceRequest struct {
3131
Service string `json:"service"`
3232
Method string `json:"method"`
3333
Options TaskOptions `json:"options"`
34-
Input TaskInput `json:"input"`
34+
Input any `json:"input"`
35+
}
36+
37+
type ExecServiceResponse struct {
38+
IsAsync bool `json:"isAsync"`
39+
Output any `json:"output"`
40+
IsError bool `json:"isError"`
41+
Error Error `json:"error"`
3542
}
3643

3744
// PutRequest represents the JSON structure for put operations
@@ -89,11 +96,11 @@ func (sc *ServiceClient) StartApp(req StartAppRequest) error {
8996
}
9097

9198
// ExecService executes a service with the given request
92-
func (sc *ServiceClient) ExecService(sessionId string, req ExecServiceRequest) (TaskOutput, error) {
93-
var res TaskOutput
99+
func (sc *ServiceClient) ExecService(sessionId string, req ExecServiceRequest) (ExecServiceResponse, error) {
100+
var res ExecServiceResponse
94101
err := executeApiWithResponse(sc.httpClient, sc.baseURL, sessionId, "v1/context/service/exec", req, &res)
95102
if err != nil {
96-
return TaskOutput{}, err
103+
return ExecServiceResponse{}, err
97104
}
98105

99106
if res.IsAsync {

polycode/model.go

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,28 +29,30 @@ func (t TaskOptions) WithTimeout(timeout time.Duration) TaskOptions {
2929
return t
3030
}
3131

32-
type TaskInput struct {
33-
Checksum uint64 `json:"checksum"`
34-
Input any `json:"input"`
32+
type ServiceStartEvent struct {
33+
SessionId string `json:"sessionId"`
34+
Service string `json:"service"`
35+
Method string `json:"method"`
36+
Input any `json:"input"`
3537
}
3638

37-
type TaskOutput struct {
38-
IsAsync bool `json:"isAsync"`
39+
type ServiceCompleteEvent struct {
3940
IsError bool `json:"isError"`
4041
Output any `json:"output"`
4142
Error Error `json:"error"`
4243
}
4344

44-
type TaskCompleteEvent struct {
45-
Output TaskOutput
45+
type ApiStartEvent struct {
46+
SessionId string `json:"sessionId"`
47+
Request ApiRequest `json:"request"`
48+
}
49+
50+
type ApiCompleteEvent struct {
51+
Response ApiResponse `json:"response"`
4652
}
4753

48-
type TaskStartEvent struct {
49-
SessionId string `json:"sessionId"`
50-
ServiceName string `json:"serviceName"`
51-
EntryPoint string `json:"entryPoint"`
52-
Input TaskInput `json:"input"`
53-
Options TaskOptions `json:"options"`
54+
type ErrorEvent struct {
55+
Error Error
5456
}
5557

5658
type ApiRequest struct {
@@ -70,13 +72,6 @@ type ApiResponse struct {
7072
IsBase64Encoded bool `json:"isBase64Encoded"`
7173
}
7274

73-
type ApiStartEvent struct {
74-
SessionId string `json:"sessionId"`
75-
Controller string `json:"controller"`
76-
Request ApiRequest `json:"request"`
77-
Options TaskOptions `json:"options"`
78-
}
79-
8075
type RouteData struct {
8176
Method string `json:"method"`
8277
Path string `json:"path"`

polycode/runtime.go

Lines changed: 51 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -129,57 +129,55 @@ func loadRoutes() []RouteData {
129129
return routes
130130
}
131131

132-
func runTask(ctx context.Context, event TaskStartEvent) (evt TaskCompleteEvent) {
132+
func runService(ctx context.Context, event ServiceStartEvent) (evt ServiceCompleteEvent, err error) {
133133
log.Println("client: handle task start event")
134134
defer func() {
135135
// Recover from panic and check for a specific error
136136
if r := recover(); r != nil {
137-
err, ok := r.(error)
137+
recovered, ok := r.(error)
138138

139-
if ok && errors.Is(err, ErrTaskInProgress) {
139+
if ok && errors.Is(recovered, ErrTaskInProgress) {
140140
log.Println("client: task in progress")
141-
evt = ValueToTaskComplete(nil)
141+
evt = ValueToServiceComplete(nil)
142142
} else {
143-
log.Printf("client: task completed with error %s\n", err.Error())
143+
log.Printf("client: task error %s\n", recovered.Error())
144144
stackTrace := string(debug.Stack())
145145
println(stackTrace)
146-
evt = ErrorToTaskComplete(err)
146+
err = recovered
147147
}
148148
}
149149
}()
150150

151-
service, err := getService(event.ServiceName)
151+
service, err := getService(event.Service)
152152
if err != nil {
153-
fmt.Printf("client: task completed with error %s\n", err.Error())
154-
return ErrorToTaskComplete(err)
153+
fmt.Printf("client: task error %s\n", err.Error())
154+
return ServiceCompleteEvent{}, err
155155
}
156156

157-
inputObj, err := service.GetInputType(event.EntryPoint)
157+
inputObj, err := service.GetInputType(event.Method)
158158
if err != nil {
159-
fmt.Printf("client: task completed with error %s\n", err.Error())
160-
return ErrorToTaskComplete(err)
159+
fmt.Printf("client: task error %s\n", err.Error())
160+
return ServiceCompleteEvent{}, err
161161
}
162162

163-
err = ConvertType(event.Input.Input, inputObj)
163+
err = ConvertType(event.Input, inputObj)
164164
if err != nil {
165-
fmt.Printf("client: task completed with error %s\n", err.Error())
166-
return ErrorToTaskComplete(err)
165+
fmt.Printf("client: task error %s\n", err.Error())
166+
return ServiceCompleteEvent{}, err
167167
}
168168

169-
isWorkflow := service.IsWorkflow(event.EntryPoint)
170-
171169
var ret any
172-
if isWorkflow {
170+
if service.IsWorkflow(event.Method) {
173171
workflowCtx := WorkflowContext{
174172
ctx: ctx,
175173
sessionId: event.SessionId,
176174
serviceClient: serviceClient,
177175
config: appConfig,
178176
}
179177

180-
println(fmt.Sprintf("client: service %s exec workflow %s with session id %s", event.ServiceName,
181-
event.EntryPoint, event.SessionId))
182-
ret, err = service.ExecuteWorkflow(workflowCtx, event.EntryPoint, inputObj)
178+
println(fmt.Sprintf("client: service %s exec workflow %s with session id %s", event.Service,
179+
event.Method, event.SessionId))
180+
ret, err = service.ExecuteWorkflow(workflowCtx, event.Method, inputObj)
183181
} else {
184182
srvCtx := ServiceContext{
185183
ctx: ctx,
@@ -188,42 +186,49 @@ func runTask(ctx context.Context, event TaskStartEvent) (evt TaskCompleteEvent)
188186
config: appConfig,
189187
}
190188

191-
println(fmt.Sprintf("client: service %s exec handler %s with session id %s", event.ServiceName,
192-
event.EntryPoint, event.SessionId))
193-
ret, err = service.ExecuteService(srvCtx, event.EntryPoint, inputObj)
189+
println(fmt.Sprintf("client: service %s exec handler %s with session id %s", event.Service,
190+
event.Method, event.SessionId))
191+
ret, err = service.ExecuteService(srvCtx, event.Method, inputObj)
194192
}
195193

196194
if err != nil {
197195
fmt.Printf("client: task completed with error %s\n", err.Error())
198-
return ErrorToTaskComplete(err)
196+
return ErrorToServiceComplete(err), nil
199197
}
200198

201199
println("client: task completed")
202-
return ValueToTaskComplete(ret)
200+
return ValueToServiceComplete(ret), nil
203201
}
204202

205-
func runApi(ctx context.Context, event ApiStartEvent) (evt TaskCompleteEvent) {
203+
func runApi(ctx context.Context, event ApiStartEvent) (evt ApiCompleteEvent, err error) {
206204
log.Println("client: handle http request")
207205
defer func() {
208206
// Recover from panic and check for a specific error
209207
if r := recover(); r != nil {
210-
err, ok := r.(error)
208+
recovered, ok := r.(error)
211209

212-
if ok && errors.Is(err, ErrTaskInProgress) {
210+
if ok && errors.Is(recovered, ErrTaskInProgress) {
213211
log.Println("client: api in progress")
214-
evt = ValueToTaskComplete(nil)
212+
evt = ApiCompleteEvent{
213+
Response: ApiResponse{
214+
StatusCode: 200,
215+
Header: make(map[string]string),
216+
Body: "",
217+
IsBase64Encoded: false,
218+
},
219+
}
215220
} else {
216-
log.Printf("client: api completed with error %s\n", err.Error())
221+
log.Printf("client: api error %s\n", recovered.Error())
217222
stackTrace := string(debug.Stack())
218223
println(stackTrace)
219-
evt = ErrorToTaskComplete(err)
224+
err = recovered
220225
}
221226
}
222227
}()
223228

224229
if httpHandler == nil {
225-
log.Printf("client: task completed with error %s\n", ErrBadRequest.Error())
226-
return ErrorToTaskComplete(ErrBadRequest)
230+
println("client: api error, not registered")
231+
return ApiCompleteEvent{}, fmt.Errorf("api not registered")
227232
}
228233

229234
apiCtx := ApiContext{
@@ -232,38 +237,32 @@ func runApi(ctx context.Context, event ApiStartEvent) (evt TaskCompleteEvent) {
232237
serviceClient: serviceClient,
233238
config: appConfig,
234239
}
235-
newCtx := context.WithValue(ctx, "polycode.context", apiCtx)
236240

237-
res, err := invokeHandler(newCtx, httpHandler, event.Request)
241+
newCtx := context.WithValue(ctx, "polycode.context", apiCtx)
242+
httpReq, err := convertToHttpRequest(newCtx, event.Request)
238243
if err != nil {
239-
fmt.Printf("client: task completed with error %s\n", err.Error())
240-
return ErrorToTaskComplete(err)
244+
return ApiCompleteEvent{}, err
241245
}
242246

243-
println("client: task completed")
244-
return ValueToTaskComplete(res)
247+
res := invokeHandler(httpHandler, httpReq)
248+
println("client: api completed")
249+
return ApiCompleteEvent{
250+
Response: res,
251+
}, nil
245252
}
246253

247-
func ValueToTaskComplete(output any) TaskCompleteEvent {
248-
taskOutput := TaskOutput{
254+
func ValueToServiceComplete(output any) ServiceCompleteEvent {
255+
return ServiceCompleteEvent{
249256
Output: output,
250257
IsError: false,
251258
Error: Error{},
252259
}
253-
254-
return TaskCompleteEvent{
255-
Output: taskOutput,
256-
}
257260
}
258261

259-
func ErrorToTaskComplete(err error) TaskCompleteEvent {
260-
taskOutput := TaskOutput{
262+
func ErrorToServiceComplete(err error) ServiceCompleteEvent {
263+
return ServiceCompleteEvent{
261264
Output: nil,
262265
IsError: true,
263266
Error: ErrTaskExecError.Wrap(err),
264267
}
265-
266-
return TaskCompleteEvent{
267-
Output: taskOutput,
268-
}
269268
}

polycode/service.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,11 @@ type RemoteService struct {
4343
}
4444

4545
func (r RemoteService) RequestReply(options TaskOptions, method string, input any) Response {
46-
taskInput := TaskInput{
47-
Input: input,
48-
}
49-
5046
req := ExecServiceRequest{
5147
Service: r.service,
5248
Method: method,
5349
Options: options,
54-
Input: taskInput,
50+
Input: input,
5551
}
5652

5753
output, err := r.serviceClient.ExecService(r.sessionId, req)

polycode/web.go

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"encoding/base64"
7-
"fmt"
87
"io"
98
"mime"
109
"net/http"
@@ -158,16 +157,8 @@ func convertToHttpRequest(ctx context.Context, apiReq ApiRequest) (*http.Request
158157
}
159158

160159
// Manually invoke an HTTP handler
161-
func invokeHandler(ctx context.Context, handler http.Handler, req ApiRequest) (ApiResponse, error) {
162-
fmt.Printf("client: invokeHandler request: %v\n", req)
163-
httpReq, err := convertToHttpRequest(ctx, req)
164-
if err != nil {
165-
return ApiResponse{}, err
166-
}
167-
160+
func invokeHandler(handler http.Handler, httpReq *http.Request) ApiResponse {
168161
customWriter := &ResponseWriter{}
169162
handler.ServeHTTP(customWriter, httpReq)
170-
res := customWriter.End()
171-
fmt.Printf("client: invokeHandler response: %v\n", res)
172-
return res, nil
163+
return customWriter.End()
173164
}

0 commit comments

Comments
 (0)