Skip to content

Handle Signal Exceptions during Runtime API Http Requests Gracefully and Version Bump to 3.1.3 #50

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 11, 2025

Conversation

M-Elsaeed
Copy link
Contributor

@M-Elsaeed M-Elsaeed commented Jun 9, 2025

Handle Signal Exceptions during Runtime API Http Requests Gracefully and Version Bump to 3.1.3

Issue #, if available: #28

Description of changes: Handle the Ruby HTTP library SignalExceptions when receiving SIGTERM/SIGKILL/Interrupt/etc... and shutdown gracefully without polluting customer logs with a false positive exception log.

Target (OCI, Managed Runtime, both): Managed Runtimes (When using Extensions).

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@M-Elsaeed M-Elsaeed changed the title Handle Interrupts to the Runtime API Http Requests Gracefully and Version Bump to 3.1.3 Handle Signal Exceptions during Runtime API Http Requests Gracefully and Version Bump to 3.1.3 Jun 9, 2025
@M-Elsaeed
Copy link
Contributor Author

Testing

The added snippet in the ruby code gracefully handles exceptions caused by Signals (such as SIGTERM) and interrupts (child of SignalException).

rescue SignalException => sig
    puts "Next invocation HTTP request from the runtime interface client was interrupted with a #{sig} SIGNAL, gracefully shutting down."
    exit 0
  • The interrupt is done by control+c and produces the same stack trace in the Issue with out that snippet, and shuts down gracefully with it.

  • SIGTERM is done by running kill -TERM <process-id>. You might not see the same stack trace when testing locally, but you will see the graceful shutdown with the snippet.

I tested this with Ruby 3.2, 3.3, and 3.4.


Setup to test

Tested this by using a local express server

const express = require('express')
const app = express()
const port = 3000
const sleep = (waitTimeInMs) => new Promise(resolve => setTimeout(resolve, waitTimeInMs));

app.get('/', async (req, res) => {
    await sleep(2000)
    res.send('Hello World!')
})

app.listen(port, () => {
    console.log(`Example app listening on port ${port}`)
})

Local Ruby Code to Test this

require 'net/http'

def next_invocation
  next_invocation_uri = URI('http://127.0.0.1:3000/')
  begin
    http = Net::HTTP.new(next_invocation_uri.host, next_invocation_uri.port)
    resp = http.start do |connection|
      connection.get(next_invocation_uri.path)
    end
    if resp.is_a?(Net::HTTPSuccess)
      puts resp
    else
      puts 'Received when waiting for next invocation.'
    end
  # rescue SignalException => sig
  #   puts "Next invocation HTTP request from the runtime interface client was interrupted with a #{sig} SIGNAL, gracefully shutting down."
  #   exit 0
  rescue => e
    puts e
  end
end

puts "PID: #{Process.pid}"


while true
  next_invocation()
end
@M-Elsaeed M-Elsaeed marked this pull request as ready for review June 9, 2025 16:46
@M-Elsaeed M-Elsaeed merged commit d6f4cb4 into main Jun 11, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
3 participants