Skip to content

Commit 068a324

Browse files
aws-sam-tooling-bot[bot]lambda-tooling+rie
andauthored
Update from upstream - 2026-09-23 (#191)
Co-authored-by: lambda-tooling+rie <lambda-tooling+rie@amazon.com>
1 parent 3ccddd7 commit 068a324

46 files changed

Lines changed: 2240 additions & 274 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎internal/lambda-managed-instances/aws-lambda-rie/internal/app.go‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func (h *HTTPHandler) invoke(w http.ResponseWriter, r *http.Request) {
6969

7070
metrics := invoke.NewInvokeMetrics(nil, &noOpCounter{})
7171
metrics.AttachInvokeRequest(invokeReq)
72-
if err, responseSent := h.app.Invoke(ctx, invokeReq, metrics); err != nil {
72+
if err, responseSent, _ := h.app.Invoke(ctx, invokeReq, metrics, w); err != nil {
7373
logging.Err(ctx, "invoke failed", err)
7474
if !responseSent {
7575
h.respondWithError(w, err)
@@ -93,7 +93,7 @@ func (h *HTTPHandler) respondWithError(w http.ResponseWriter, err rapidmodel.App
9393

9494
type raptorApp interface {
9595
Init(ctx context.Context, req *intmodel.InitRequestMessage, metrics interop.InitMetrics) rapidmodel.AppError
96-
Invoke(ctx context.Context, msg interop.InvokeRequest, metrics interop.InvokeMetrics) (err rapidmodel.AppError, responseSent bool)
96+
Invoke(ctx context.Context, msg interop.InvokeRequest, metrics interop.InvokeMetrics, responseWriter http.ResponseWriter) (err rapidmodel.AppError, responseSent bool, invokePending bool)
9797
}
9898

9999
type noOpCounter struct{}

‎internal/lambda-managed-instances/aws-lambda-rie/internal/invoke/responder.go‎

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ import (
1616
)
1717

1818
type Responder struct {
19-
invokeReq interop.InvokeRequest
20-
body []byte
21-
rw http.ResponseWriter
19+
invokeReq interop.InvokeRequest
20+
body []byte
21+
responseWriter http.ResponseWriter
2222
}
2323

24-
func NewResponder(invokeReq interop.InvokeRequest) *Responder {
24+
func NewResponder(invokeReq interop.InvokeRequest, responseWriter http.ResponseWriter) *Responder {
2525
return &Responder{
26-
invokeReq: invokeReq,
27-
rw: invokeReq.ResponseWriter(),
26+
invokeReq: invokeReq,
27+
responseWriter: responseWriter,
2828
}
2929
}
3030

@@ -60,9 +60,9 @@ func (s *Responder) SendRuntimeResponseTrailers(request invoke.RuntimeResponseRe
6060
s.SendErrorTrailers(trailerError, "")
6161
return
6262
}
63-
s.rw.Header().Set(invoke.СontentTypeHeader, request.ContentType())
64-
s.rw.Header().Set(invoke.RuntimeResponseModeHeader, request.ResponseMode())
65-
if _, err := s.rw.Write(s.body); err != nil {
63+
s.responseWriter.Header().Set(invoke.СontentTypeHeader, request.ContentType())
64+
s.responseWriter.Header().Set(invoke.RuntimeResponseModeHeader, request.ResponseMode())
65+
if _, err := s.responseWriter.Write(s.body); err != nil {
6666
slog.Error("could not write invoke response", "err", err)
6767
}
6868
}
@@ -72,10 +72,10 @@ func (s *Responder) SendError(err invoke.ErrorForInvoker, _ interop.InitStaticDa
7272
}
7373

7474
func (s *Responder) SendErrorTrailers(err invoke.ErrorForInvoker, _ invoke.InvokeBodyResponseStatus) {
75-
s.rw.Header().Set("Error-Type", err.ErrorType().String())
75+
s.responseWriter.Header().Set("Error-Type", err.ErrorType().String())
7676

77-
s.rw.WriteHeader(err.ReturnCode())
78-
if _, err := s.rw.Write([]byte(err.ErrorDetails())); err != nil {
77+
s.responseWriter.WriteHeader(err.ReturnCode())
78+
if _, err := s.responseWriter.Write([]byte(err.ErrorDetails())); err != nil {
7979
slog.Error("could not write invoke error response", "err", err)
8080
}
8181
}

‎internal/lambda-managed-instances/aws-lambda-rie/internal/invoke/responder_test.go‎

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ func TestResponder_CompleteSuccessFlow(t *testing.T) {
2525
mockRuntimeReq := invoke.NewMockRuntimeResponseRequest(t)
2626
mockInitData := interop.NewMockInitStaticDataProvider(t)
2727

28-
mockInvokeReq.On("ResponseWriter").Return(recorder)
2928
mockInvokeReq.On("MaxPayloadSize").Return(int64(1024))
3029

3130
responseBody := "test response body"
@@ -34,7 +33,7 @@ func TestResponder_CompleteSuccessFlow(t *testing.T) {
3433
mockRuntimeReq.On("ResponseMode").Return("buffered")
3534
mockRuntimeReq.On("TrailerError").Return(nil)
3635

37-
responder := NewResponder(mockInvokeReq)
36+
responder := NewResponder(mockInvokeReq, recorder)
3837
responder.SendRuntimeResponseHeaders(mockInitData, "", "")
3938
result := responder.SendRuntimeResponseBody(context.Background(), mockRuntimeReq, 0)
4039
assert.NoError(t, result.Err)
@@ -55,12 +54,10 @@ func TestResponder_SendErrorFlow(t *testing.T) {
5554
mockInvokeReq := interop.NewMockInvokeRequest(t)
5655
mockInitData := interop.NewMockInitStaticDataProvider(t)
5756

58-
mockInvokeReq.On("ResponseWriter").Return(recorder)
59-
6057
baseErr := io.ErrUnexpectedEOF
6158
appError := model.NewCustomerError("Function.TestError", model.WithCause(baseErr), model.WithErrorMessage("test error"))
6259

63-
responder := NewResponder(mockInvokeReq)
60+
responder := NewResponder(mockInvokeReq, recorder)
6461
responder.SendError(appError, mockInitData)
6562

6663
assert.Equal(t, "Function.TestError", recorder.Header().Get("Error-Type"))
@@ -76,9 +73,7 @@ func TestResponder_RuntimeInvocationErrorFlow(t *testing.T) {
7673
mockInvokeReq := interop.NewMockInvokeRequest(t)
7774
mockInitData := interop.NewMockInitStaticDataProvider(t)
7875

79-
mockInvokeReq.On("ResponseWriter").Return(recorder)
80-
81-
responder := NewResponder(mockInvokeReq)
76+
responder := NewResponder(mockInvokeReq, recorder)
8277
responder.SendRuntimeResponseHeaders(mockInitData, "", "")
8378
responder.SendErrorTrailers(model.NewCustomerError("Runtime.TestError", model.WithErrorMessage("trailer error")), "")
8479

@@ -96,13 +91,12 @@ func TestResponder_ErrorInTheMiddleOfResponse(t *testing.T) {
9691
mockRuntimeReq := invoke.NewMockRuntimeResponseRequest(t)
9792
mockInitData := interop.NewMockInitStaticDataProvider(t)
9893

99-
mockInvokeReq.On("ResponseWriter").Return(recorder)
10094
mockInvokeReq.On("MaxPayloadSize").Return(int64(1024))
10195

10296
responseBody := "test response body"
10397
mockRuntimeReq.On("BodyReader").Return(strings.NewReader(responseBody))
10498

105-
responder := NewResponder(mockInvokeReq)
99+
responder := NewResponder(mockInvokeReq, recorder)
106100
responder.SendRuntimeResponseHeaders(mockInitData, "", "")
107101
result := responder.SendRuntimeResponseBody(context.Background(), mockRuntimeReq, 0)
108102
assert.NoError(t, result.Err)
@@ -123,7 +117,6 @@ func TestResponder_RuntimeResponseTrailerError(t *testing.T) {
123117
mockRuntimeReq := invoke.NewMockRuntimeResponseRequest(t)
124118
mockInitData := interop.NewMockInitStaticDataProvider(t)
125119

126-
mockInvokeReq.On("ResponseWriter").Return(recorder)
127120
mockInvokeReq.On("MaxPayloadSize").Return(int64(1024))
128121

129122
errorType := model.ErrorType("Function.TrailerError")
@@ -138,7 +131,7 @@ func TestResponder_RuntimeResponseTrailerError(t *testing.T) {
138131
mockRuntimeReq.On("BodyReader").Return(strings.NewReader(responseBody))
139132
mockRuntimeReq.On("TrailerError").Return(trailerError)
140133

141-
responder := NewResponder(mockInvokeReq)
134+
responder := NewResponder(mockInvokeReq, recorder)
142135
responder.SendRuntimeResponseHeaders(mockInitData, "", "")
143136
result := responder.SendRuntimeResponseBody(context.Background(), mockRuntimeReq, 0)
144137
assert.NoError(t, result.Err)
@@ -188,10 +181,9 @@ func TestResponder_SendRuntimeResponseBody(t *testing.T) {
188181
mockInvokeReq := interop.NewMockInvokeRequest(t)
189182
mockRuntimeReq := invoke.NewMockRuntimeResponseRequest(t)
190183

191-
mockInvokeReq.On("ResponseWriter").Return(recorder)
192184
tt.setupMocks(mockInvokeReq, mockRuntimeReq)
193185

194-
responder := NewResponder(mockInvokeReq)
186+
responder := NewResponder(mockInvokeReq, recorder)
195187
result := responder.SendRuntimeResponseBody(context.Background(), mockRuntimeReq, 0)
196188

197189
if tt.expectError {

‎internal/lambda-managed-instances/aws-lambda-rie/internal/invoke/rie_invoke_request.go‎

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ type rieInvokeRequest struct {
4242
responseMode string
4343
internalInvocationID string
4444

45-
functionVersionID string
45+
functionVersionID string
46+
resolvedInvokeTimeout time.Duration
4647
}
4748

4849
func NewRieInvokeRequest(request *http.Request, writer http.ResponseWriter) (*rieInvokeRequest, model.AppError) {
@@ -149,22 +150,6 @@ func (r *rieInvokeRequest) BodyReader() io.Reader {
149150
return r.request.Body
150151
}
151152

152-
func (r *rieInvokeRequest) ResponseWriter() http.ResponseWriter {
153-
return r.writer
154-
}
155-
156-
func (r *rieInvokeRequest) SetResponseHeader(key string, val string) {
157-
r.writer.Header().Set(key, val)
158-
}
159-
160-
func (r *rieInvokeRequest) AddResponseHeader(key string, val string) {
161-
r.writer.Header().Add(key, val)
162-
}
163-
164-
func (r *rieInvokeRequest) WriteResponseHeaders(status int) {
165-
r.writer.WriteHeader(status)
166-
}
167-
168153
func (r *rieInvokeRequest) ResponseMode() string {
169154
return r.responseMode
170155
}
@@ -174,7 +159,8 @@ func (r *rieInvokeRequest) UpdateFromInitData(initData interop.InitStaticDataPro
174159
return model.NewClientError(errors.New("sandbox is not initialized"), model.ErrorSeverityError, model.ErrorInitIncomplete)
175160
}
176161

177-
r.deadline = time.Now().Add(time.Duration(initData.FunctionTimeout()) * time.Millisecond)
162+
r.resolvedInvokeTimeout = initData.FunctionTimeout()
163+
r.deadline = time.Now().Add(r.resolvedInvokeTimeout)
178164

179165
if r.functionVersionID != initData.FunctionVersionID() {
180166
return model.NewClientError(nil, model.ErrorSeverityInvalid, model.ErrorInvalidFunctionVersion)
@@ -187,6 +173,14 @@ func (r *rieInvokeRequest) FunctionVersionID() string {
187173
return r.functionVersionID
188174
}
189175

190-
func (r *rieInvokeRequest) InternalInvocationID() string {
191-
return r.internalInvocationID
176+
func (r *rieInvokeRequest) ResolvedFunctionTimeoutMs() int64 {
177+
return 0
178+
}
179+
180+
func (r *rieInvokeRequest) ResolvedInvokeTimeout() time.Duration {
181+
return r.resolvedInvokeTimeout
192182
}
183+
184+
func (r *rieInvokeRequest) LongPollingConfig() *interop.LongPollingConfig { return nil }
185+
186+
func (r *rieInvokeRequest) InternalInvocationID() string { return r.internalInvocationID }

‎internal/lambda-managed-instances/aws-lambda-rie/internal/mock_raptor_app.go‎

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package internal
55

66
import (
77
context "context"
8+
http "net/http"
89

910
mock "github.com/stretchr/testify/mock"
1011
interop "github.com/aws/aws-lambda-runtime-interface-emulator/internal/lambda-managed-instances/interop"
@@ -37,33 +38,40 @@ func (_m *mockRaptorApp) Init(ctx context.Context, req *model.InitRequestMessage
3738
return r0
3839
}
3940

40-
func (_m *mockRaptorApp) Invoke(ctx context.Context, msg interop.InvokeRequest, metrics interop.InvokeMetrics) (rapidmodel.AppError, bool) {
41-
ret := _m.Called(ctx, msg, metrics)
41+
func (_m *mockRaptorApp) Invoke(ctx context.Context, msg interop.InvokeRequest, metrics interop.InvokeMetrics, responseWriter http.ResponseWriter) (rapidmodel.AppError, bool, bool) {
42+
ret := _m.Called(ctx, msg, metrics, responseWriter)
4243

4344
if len(ret) == 0 {
4445
panic("no return value specified for Invoke")
4546
}
4647

4748
var r0 rapidmodel.AppError
4849
var r1 bool
49-
if rf, ok := ret.Get(0).(func(context.Context, interop.InvokeRequest, interop.InvokeMetrics) (rapidmodel.AppError, bool)); ok {
50-
return rf(ctx, msg, metrics)
50+
var r2 bool
51+
if rf, ok := ret.Get(0).(func(context.Context, interop.InvokeRequest, interop.InvokeMetrics, http.ResponseWriter) (rapidmodel.AppError, bool, bool)); ok {
52+
return rf(ctx, msg, metrics, responseWriter)
5153
}
52-
if rf, ok := ret.Get(0).(func(context.Context, interop.InvokeRequest, interop.InvokeMetrics) rapidmodel.AppError); ok {
53-
r0 = rf(ctx, msg, metrics)
54+
if rf, ok := ret.Get(0).(func(context.Context, interop.InvokeRequest, interop.InvokeMetrics, http.ResponseWriter) rapidmodel.AppError); ok {
55+
r0 = rf(ctx, msg, metrics, responseWriter)
5456
} else {
5557
if ret.Get(0) != nil {
5658
r0 = ret.Get(0).(rapidmodel.AppError)
5759
}
5860
}
5961

60-
if rf, ok := ret.Get(1).(func(context.Context, interop.InvokeRequest, interop.InvokeMetrics) bool); ok {
61-
r1 = rf(ctx, msg, metrics)
62+
if rf, ok := ret.Get(1).(func(context.Context, interop.InvokeRequest, interop.InvokeMetrics, http.ResponseWriter) bool); ok {
63+
r1 = rf(ctx, msg, metrics, responseWriter)
6264
} else {
6365
r1 = ret.Get(1).(bool)
6466
}
6567

66-
return r0, r1
68+
if rf, ok := ret.Get(2).(func(context.Context, interop.InvokeRequest, interop.InvokeMetrics, http.ResponseWriter) bool); ok {
69+
r2 = rf(ctx, msg, metrics, responseWriter)
70+
} else {
71+
r2 = ret.Get(2).(bool)
72+
}
73+
74+
return r0, r1, r2
6775
}
6876

6977
func newMockRaptorApp(t interface {

‎internal/lambda-managed-instances/aws-lambda-rie/internal/run.go‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"context"
88
"fmt"
99
"log/slog"
10+
"net/http"
1011
"os"
1112
"time"
1213

@@ -47,10 +48,10 @@ func Run(supv supvmodel.ProcessSupervisor, args []string, fileUtil utils.FileUti
4748
telemetryAPIRelay := telemetry.NewRelay()
4849
eventsAPI := telemetry.NewEventsAPI(telemetryAPIRelay)
4950

50-
responderFactoryFunc := func(_ context.Context, invokeReq interop.InvokeRequest) invoke.InvokeResponseSender {
51-
return rieinvoke.NewResponder(invokeReq)
52-
}
53-
invokeRouter := invoke.NewInvokeRouter(rapid.RuntimePoolSize, eventsAPI, responderFactoryFunc, timeout.NewRecentCache())
51+
invokeRouter := invoke.NewInvokeRouter(rapid.RuntimePoolSize, eventsAPI, timeout.NewRecentCache())
52+
longPollRouter := invoke.NewLongInvokerRouter(invokeRouter, func(_ context.Context, invokeReq interop.InvokeRequest, responseWriter http.ResponseWriter) invoke.InvokeResponseSender {
53+
return rieinvoke.NewResponder(invokeReq, responseWriter)
54+
})
5455

5556
metadataToken := uuid.NewString()
5657
deps := rapid.Dependencies{
@@ -60,7 +61,7 @@ func Run(supv supvmodel.ProcessSupervisor, args []string, fileUtil utils.FileUti
6061
Supervisor: supv,
6162
RuntimeAPIAddrPort: runtimeAPIAddr,
6263
FileUtils: fileUtil,
63-
InvokeRouter: invokeRouter,
64+
InvokeRouter: longPollRouter,
6465
MetadataService: lmds.NewService(metadataToken),
6566
}
6667

‎internal/lambda-managed-instances/interop/mock_init_static_data_provider.go‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,23 @@ func (_m *MockInitStaticDataProvider) MemorySizeMB() uint64 {
201201
return r0
202202
}
203203

204+
func (_m *MockInitStaticDataProvider) RuntimeRelease() string {
205+
ret := _m.Called()
206+
207+
if len(ret) == 0 {
208+
panic("no return value specified for RuntimeRelease")
209+
}
210+
211+
var r0 string
212+
if rf, ok := ret.Get(0).(func() string); ok {
213+
r0 = rf()
214+
} else {
215+
r0 = ret.Get(0).(string)
216+
}
217+
218+
return r0
219+
}
220+
204221
func (_m *MockInitStaticDataProvider) RuntimeVersion() string {
205222
ret := _m.Called()
206223

‎internal/lambda-managed-instances/interop/mock_invoke_metrics.go‎

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,43 @@ func (_m *MockInvokeMetrics) SendMetrics(_a0 model.AppError) error {
7474
return r0
7575
}
7676

77+
func (_m *MockInvokeMetrics) SetInvokeMode(mode string) {
78+
_m.Called(mode)
79+
}
80+
7781
func (_m *MockInvokeMetrics) SetReservationUsed(wasReserved bool) {
7882
_m.Called(wasReserved)
7983
}
8084

81-
func (_m *MockInvokeMetrics) TriggerGetRequest() {
85+
func (_m *MockInvokeMetrics) SetResponseDeliveryLost() {
86+
_m.Called()
87+
}
88+
89+
func (_m *MockInvokeMetrics) SetResponseDeliverySent() {
8290
_m.Called()
8391
}
8492

93+
func (_m *MockInvokeMetrics) SetResponseWaitTime(d time.Duration) {
94+
_m.Called(d)
95+
}
96+
97+
func (_m *MockInvokeMetrics) TriggerGetRequest() time.Time {
98+
ret := _m.Called()
99+
100+
if len(ret) == 0 {
101+
panic("no return value specified for TriggerGetRequest")
102+
}
103+
104+
var r0 time.Time
105+
if rf, ok := ret.Get(0).(func() time.Time); ok {
106+
r0 = rf()
107+
} else {
108+
r0 = ret.Get(0).(time.Time)
109+
}
110+
111+
return r0
112+
}
113+
85114
func (_m *MockInvokeMetrics) TriggerGetResponse() {
86115
_m.Called()
87116
}

0 commit comments

Comments
 (0)