Error: Unable to perform the request: Timeout was reached (Couchbase Eventing)

Issue - Error: Unable to perform the request: Timeout was reached.

Error log in eventing - 2021-11-23T11:44:19.025+00:00 [INFO] “error occured while calling the api for meta.id : new_doc_5, error : Error: Unable to perform the request: Timeout was reached”

complete post URL → https://working.url/test (I’ve changed the URL for security reasons but the original URL is a working URL )

eventing setting
url alias → curlBackend → https://working.url

eventing js code snippet
function OnUpdate(doc, meta) {
var request = {
path: ‘/test’,
headers: {
‘Secret-Key’: ‘HSOSJBSOJ19203092AJSJSDIK’
},
body: {
“doc”: doc,
“metadata”: meta
}
};
try {
if (Object.keys(request.body.doc).length > 0) {
if (‘data’ in request.body.doc) {
log("-----------------transaction started-------------------");
log(“document : " + JSON.stringify(request.body.doc));
var response = curl(‘POST’, curlBackend, request);
if (response && response.status == ‘200’) {
log(“completed”);
} else {
log(“failed”);
}
log(”-----------------transaction completed-------------------");
}
}
} catch (err) {
log("error occured while calling the api for meta.id : " + meta.id + ", error : " + err);
}
}

CURL() Function Access is in Unrestricted mode

Please help me in solving this as I’m new to all this

ping from couchbase server is also not working due to which the above issue is coming.
please help how to resolve this

[satish@couchbase-alpha-jkt logs]$ ping google.com
PING google.com (142.251.12.139) 56(84) bytes of data.

Hi @satish_kumar,

ping from couchbase server is also not working due to which the above issue is coming.

The ability to access your REST endpoint from all Eventing nodes is the first item to verify/fix. As ping may be blocked I would try to use either curl or wget command line utilities from a shell session on each eventing node to exercise the target REST endpoint. Pay attention to the “time” it takes for your HTTPS request to complete. I am thinking you most likely have a firewall issue.

Now about the error “Error: Unable to perform the request: Timeout was reached” once you get the curl command line utility working correctly you should no longer see this provided your REST API response time is under 30 seconds.

There are two timeouts to consider

  1. an Eventing Script timeout which is adjustable in the Eventing Function’s settings (and set to 60 seconds by default). What this means if your curl() transaction does not complete within about 2 seconds of this timeout the v8 runner will be terminated and your lambda will be aborted with the message you see above "Error: Unable to perform the request: Timeout was reached"

  2. The second possible timeout is a CURL timeout which I initially thought was is 30 seconds but seems to be infinite by default (via actual testing). This should not be impacting you at all.

However I would argue that a REST endpoint that exceeds 60 seconds (or even 1 second) is a performance killer. Consider if your Function settings has 3 Eventing workers (each work has two threads) - this gives you just 6 threads of execution. Now if you are blocking for 30 seconds on each thread you could only processes one item every 5 seconds definitely not very performant. Even a 1 second round trip would still limit you to 6 mutations a second (if you leave the workers at 3 obviously if you had a 16 core system you might bump the worker count way up for performance) - so you really want your REST API to respond in a few milliseconds.

Best

Jon Strabala
Principal Product Manager - Server‌

1 Like

A quick follow up you can make you own web server to test things out yourself and add delays to test out the timeout behaviour.

In the python script (below) adjust # in time.sleep(#) then you can access the IP address of the server you run this on as the URL binding in Eventing. If you want to adjust the Script Timeout in the Function’s settings, expand the advanced “settings” area and change the “Script Timeout” parameter.

#!/usr/bin/env python3
"""An example HTTP server with GET and POST endpoints."""

from http.server import HTTPServer, BaseHTTPRequestHandler
from http import HTTPStatus
from datetime import datetime
import json
import time

class _RequestHandler(BaseHTTPRequestHandler):
    def _set_headers(self):
        # comment out or adjust this set it to 1, 55, and 61 with the 
        # default Eventing script timeout of 60 it will fail if you set to 61
        # with a "Unable to perform the request: Timeout was reached"
        time.sleep(55)
        self.send_response(HTTPStatus.OK.value)
        self.send_header('Content-type', 'application/json')
        self.send_header('Access-Control-Allow-Origin', '*')
        self.end_headers()

    def do_GET(self):
        message = '{"type_was":"GET"}'
        self._set_headers()
        self.wfile.write(json.dumps(message).encode('utf-8'))

    def do_POST(self):
        message = '{"type_was":"POST"}'
        self._set_headers()
        self.wfile.write(json.dumps(message).encode('utf-8'))

def run_server():
    server_address = ('', 8011)
    httpd = HTTPServer(server_address, _RequestHandler)
    print('serving at %s:%d' % server_address)
    httpd.serve_forever()

if __name__ == '__main__':
    run_server()

Hope this helps

Jon Strabala
Principal Product Manager - Server‌

thanks for the reply it really helped, I was not able to access public IPs because of server configuration but I was able to access private IPs within the VPC.
Overall there was no issue with couchbase eventing service.

Great to know @satish_kumar ! Please feel free to reach out to us in case you need any further help. Couchbase Eventing service helps come up low code solutions to hard problems with in-built parallelism. Good luck with your project. Thank you!