openfaas / connector-sdk

SDK for connecting events to functions
MIT License
54 stars 25 forks source link

Support question about MQTT Connector #64

Open aslanpour opened 2 years ago

aslanpour commented 2 years ago

My actions before raising this issue

I am using the mqtt-connector to send async requests, but it lacks some features, at least compared to HTTP async requests. My test scenario is that a client (IoT device) is invoking a function asynchronously by sending some data, say temperature value, and its identifier. The client expects the function to run some processing based on that value and return the response to the client. However, the mqtt-connector just can receive the value as a message and no call-back can be introduced, because no headers exist as in HTTP. In HTTP, the gateway is passing the request to Nats with headers (we also can include additional headers in HTTP). I think the problem is that MQTT messages directly go to Nats and do not go inside the gateway so that massages become augmented with such features (call-back, etc.).

Expected Behaviour

Async mqtt requests are expected to let Nats (or gateway--I'm not clear about the design) know about the callback and passing it to the function. Moreover, in HTTP, I needed to send a request identifier along with the request that was achievable by setting a header, but in MQTT this one is also not possible. The identifier in a header was sent back along with the callback to the client and the client was able to recognize which request is this response for.

The MQTT-connector needs to be able to receive callbacks and custom data as well as messages. The Nats server needs to treat async MQTT requests as it does for HTTP request, I mean understanding callback and headers.

Current Behaviour

Are you a GitHub Sponsor (Yes/No?)

Check at: https://github.com/sponsors/openfaas

List All Possible Solutions and Workarounds

I am unsure about my understanding of OpenFaaS design, so just to give an idea, I am telling you some possible solutions. Solution 1: Simulating HTTP headers in MQTT messages. For instance, a string pattern like "---header-X-Callback-Url:url---" inside the MQTT message. Then, once Nats receives an async MQTT message, it searches for the pattern and does the routine it does for HTTP requests, including passing the headers to queue-worker (if the routine is implemented in Nats server, not gateway).

Solution 2: Direct communication with Nats be enabled where MQTT clients do not need an MQTT broker and can just publish the request to Nats by a Nat client as encouraged in MQTT Nats. But, still sending callback and custom data remain unsolved. In this case, Nats can get the function execution output and publish it on a special subject in cae the client needs it. For instance, if the invocation subject is function/func1, then the reply from Nats is function/func1/reply.

Solution 3: As this missing callback (and other headers) might appear for other connectors (I have not tested), perhaps the best idea would be to give developers the async requests handling procedure in OpenFaaS so they can implement their own solutions. For example, instruction on how the requests are augmented by gateway (defining callback and other headers) when delivering to Nats (if a gateway to Nats communication exists in OpenFaaS); then how the Nats server is storing and augmenting the request and sending it to the queue-worker...

Which Solution Do You Recommend?

Solution 3 I really think giving a demonstration on how users can implement a procedure (from client to nats --> queue --> function --> queue --> client) for handling async requests will be helpful. For instance, how I can run a nats client that sends async requests to openfaas and receives the callback.

Steps to Reproduce (for bugs)

  1. Mqtt-connector deployment helm upgrade --install mqtt-connector mqtt-connector/ -n openfaas --namespace openfaas --set broker=tcp://10.0.0.90:1883 --set gateway_url=http://10.0.0.90:31112 --set upstream_timeout=35s --set asyncInvoke=true --set nodeSelector."kubernetes\.io/hostname"=master --set topic="/function/#"

  2. Function annotation (my function name is 'w1-short' and does some random math and returns a string text) topic: /function/w1-short

  3. Invoke the function user

  4. Mqtt-connector log mqtt-connector

  5. Queue-worker log (I can see that X-Callback-URL header is null) queue

  6. Function log function

Context

Smart Agriculture and Smart Manufacturing, where IoT devices send requests with identifiers and expect a corresponding reply from the function. Devices also care about each request and need to know which one is missed, timeout, etc. In HTTP mode, they achieve these using headers, but in MQTT they are unable to do so.

Your Environment

* FaaS-CLI version ( Full output from: `faas-cli version` ):
CLI:
 commit:  d94600d2d2be52a66e0a15c219634f3bcac27318
 version: 0.14.1

Gateway
 uri:     http://10.0.0.90:31112
 version: 0.21.1
 sha:     a9a77f0ecaa8d5a242606ceaf6deed5d8703249b

Provider
 name:          openfaas-operator
 orchestration: kubernetes
 version:       0.14.1 
 sha:           3ab2d57899704498183c8fcb30a42b35d41de8a1
alexellis commented 2 years ago

Thanks for writing up your request @aslanpour

There's a lot of detail here and I'm struggling to pin point what you're asking for, so could you clearly state what problem you're running into - perhaps in one very short paragraph?

Thanks,

Alex

alexellis commented 2 years ago

/set title: Support question about MQTT Connector

aslanpour commented 2 years ago

Thanks for writing up your request @aslanpour

There's a lot of detail here and I'm struggling to pin point what you're asking for, so could you clearly state what problem you're running into - perhaps in one very short paragraph?

Thanks,

Alex

Hi Alex,

My problem is that I cannot get the callback when I sent an async request through MQTT-connector. I also would like a demonstration of the procedure of an async request like: client --> nats --> queue --> function --> queue --> client. For instance, how is OpenFaaS creating a message out of the HTTP/MQTT request and is sending it to nats?