@@ -60,12 +60,17 @@ func main() {
6060 // pulls ELASTIC_ env variable into globals for easy access
6161 config := extension .ProcessEnv ()
6262
63- // setup http server to receive data from agent
64- // and get a channel to listen for that data
63+ // Create a channel to buffer apm agent data
6564 agentDataChannel := make (chan extension.AgentData , 100 )
6665
66+ // Start http server to receive data from agent
6767 extension .StartHttpServer (agentDataChannel , config )
6868
69+ // Create a client to use for sending data to the apm server
70+ client := & http.Client {
71+ Transport : http .DefaultTransport .(* http.Transport ).Clone (),
72+ }
73+
6974 // Make channel for collecting logs and create a HTTP server to listen for them
7075 logsChannel := make (chan logsapi.LogEvent )
7176
@@ -74,7 +79,7 @@ func main() {
7479 extensionClient .ExtensionID ,
7580 []logsapi.EventType {logsapi .Platform })
7681 if err != nil {
77- log .Printf ("Could not subscribe to the logs API. Will instead flush APM data 100ms before the function deadline. " )
82+ log .Printf ("Could not subscribe to the logs API." )
7883 } else {
7984 logsAPIListener , err := logsapi .NewLogsAPIHttpListener (logsChannel )
8085 if err != nil {
@@ -88,9 +93,6 @@ func main() {
8893 }
8994 }
9095
91- client := & http.Client {
92- Transport : http .DefaultTransport .(* http.Transport ).Clone (),
93- }
9496 for {
9597 select {
9698 case <- ctx .Done ():
@@ -107,31 +109,32 @@ func main() {
107109 }
108110 log .Printf ("Received event: %v\n " , extension .PrettyPrint (event ))
109111
112+ // Make a channel for signaling that we received the agent flushed signal
113+ extension .AgentDoneSignal = make (chan struct {})
114+ // Make a channel for signaling that we received the runtimeDone logs API event
115+ runtimeDoneSignal := make (chan struct {})
116+ // Make a channel for signaling that the function invocation is complete
117+ funcDone := make (chan struct {})
118+
119+ // Flush any APM data, in case waiting for the agentDone or runtimeDone signals
120+ // timed out, the agent data wasn't available yet, and we got to the next event
121+ extension .FlushAPMData (client , agentDataChannel , config )
122+
110123 // A shutdown event indicates the execution environment is shutting down.
111124 // This is usually due to inactivity.
112125 if event .EventType == extension .Shutdown {
113126 extension .ProcessShutdown ()
114127 return
115128 }
116129
117- // Flush any APM data, in case waiting for the runtimeDone event timed out,
118- // the agent data wasn't available yet, and we got to the next event
119- extension .FlushAPMData (client , agentDataChannel , config )
120-
121- // Make a channel for signaling that a runtimeDone event has been received
122- runtimeDone := make (chan struct {})
123-
124- // Make a channel for signaling that that function invocation has completed
125- funcInvocDone := make (chan struct {})
126-
127130 // Receive agent data as it comes in and post it to the APM server.
128131 // Stop checking for, and sending agent data when the function invocation
129132 // has completed, signaled via a channel.
130133 go func () {
131134 for {
132135 select {
133- case <- funcInvocDone :
134- log .Println ("Function invocation is complete , not receiving any more agent data" )
136+ case <- funcDone :
137+ log .Println ("funcDone signal received , not processing any more agent data" )
135138 return
136139 case agentData := <- agentDataChannel :
137140 err := extension .PostToApmServer (client , agentData , config )
@@ -143,21 +146,21 @@ func main() {
143146 }()
144147
145148 // Receive Logs API events
146- // Send to the runtimeDone channel to signal when a runtimeDone event is received
149+ // Send to the runtimeDoneSignal channel to signal when a runtimeDone event is received
147150 go func () {
148151 for {
149152 select {
150- case <- funcInvocDone :
151- log .Println ("Function invocation is complete , not receiving any more log events" )
153+ case <- funcDone :
154+ log .Println ("funcDone signal received , not processing any more log events" )
152155 return
153156 case logEvent := <- logsChannel :
154157 log .Printf ("Received log event %v\n " , logEvent .Type )
155158 // Check the logEvent for runtimeDone and compare the RequestID
156159 // to the id that came in via the Next API
157160 if logsapi .SubEventType (logEvent .Type ) == logsapi .RuntimeDone {
158161 if logEvent .Record .RequestId == event .RequestID {
159- log .Printf ("Received runtimeDone event %v" , logEvent )
160- runtimeDone <- struct {}{}
162+ log .Println ("Received runtimeDone event for this function invocation" )
163+ runtimeDoneSignal <- struct {}{}
161164 return
162165 } else {
163166 log .Println ("Log API runtimeDone event request id didn't match" )
@@ -167,7 +170,7 @@ func main() {
167170 }
168171 }()
169172
170- // Calculate how long to wait for a runtimeDone event
173+ // Calculate how long to wait for a runtimeDoneSignal or AgentDoneSignal signal
171174 flushDeadlineMs := event .DeadlineMs - 100
172175 durationUntilFlushDeadline := time .Until (time .Unix (flushDeadlineMs / 1000 , 0 ))
173176
@@ -176,17 +179,20 @@ func main() {
176179 defer timer .Stop ()
177180
178181 select {
179- case <- runtimeDone :
180- log .Println ("Received runtimeDone event signal" )
182+ case <- extension .AgentDoneSignal :
183+ log .Println ("Received agent done signal" )
184+ case <- runtimeDoneSignal :
185+ log .Println ("Received runtimeDone signal" )
181186 case <- timer .C :
182- log .Println ("Time expired waiting for runtimeDone event" )
187+ log .Println ("Time expired waiting for agent signal or runtimeDone event" )
183188 }
184189
185190 // Flush APM data now that the function invocation has completed
186191 extension .FlushAPMData (client , agentDataChannel , config )
187192
188- // Signal that the function invocation has completed
189- close (funcInvocDone )
193+ close (funcDone )
194+ close (runtimeDoneSignal )
195+ close (extension .AgentDoneSignal )
190196 }
191197 }
192198}
0 commit comments