kubemq-io / kubemq-Python

Python client for KubeMQ server https://kubemq.io
MIT License
23 stars 9 forks source link

Timestamp: invalid argument #49

Open Alessandro1996 opened 1 year ago

Alessandro1996 commented 1 year ago

I'm using kubemq to communicate with other projects, using the CQRS pattern. My project's language is Python, the other projects' language is Java. The problem I encountered happens when I receive a response of a query and process it by means of kubemq-Python libary, while the response is built using kubemq-Java library.

Here is the error traceback:

Grpc Exception in send_request:'[Errno 22] Invalid argument'
Traceback (most recent call last):
  File "project\venv\lib\site-packages\kubemq\commandquery\lowlevel\initiator.py", line 68, in send_request
    return Response(inner_response)
  File "project\venv\lib\site-packages\kubemq\commandquery\response.py", line 60, in __init__
    self.timestamp = datetime.fromtimestamp(request.Timestamp)
OSError: [Errno 22] Invalid argument

Reproduction steps

  1. [Java] Code a "handler", which simply echoes any message body of the incoming queries
  2. [Java] Subscribe to a "query channel", passing the "handler";
  3. [Python] Write a "message body", encoded in UTF-8
  4. [Python] Invoke a "send_request" with resquest="message body" and channel="query channel"
  5. [Java] Automatically execute the "handler", sending the "Response"
  6. [Python] Receive the "Response" <--- Here comes the error, while parsing the timestamp of the message

Source of error

By debugging, the source is found to be in the different way of setting the timestamp, which defers between Java and Python library. The incompatibility can be seen in the following snippets (came from the cited libraries): Java works with timestamps in milliseconds, while Python works with timestamps in seconds

Java code in kubemq-java-sdk/src/main/java/io/kubemq/sdk/commandquery/Response.java

Kubemq.Response Convert() {
    return Kubemq.Response.newBuilder()
            .setClientID(Optional.ofNullable(clientID).orElse(""))
            .setRequestID(requestID)
            .setReplyChannel(replyChannel)
            .setMetadata(Optional.ofNullable(metadata).orElse(""))
            .setBody(ByteString.copyFrom(body))
            .setCacheHit(cacheHit)
            .setTimestamp(Converter.ToUnixTime(timestamp))    <-------------------------------
            .setExecuted(executed)
            .setError(Optional.ofNullable(error).orElse(""))
            .putAllTags(Optional.ofNullable(tags).orElse(new HashMap<String,String>()))
            .build();
}

where Converter.ToUnixTime(timestamp) is in kubemq-java-sdk/src/main/java/io/kubemq/sdk/tools/Converter.java

public static long ToUnixTime(LocalDateTime timestamp) {
    return timestamp.atZone(TimeZone.getDefault().toZoneId()).toInstant().toEpochMilli();
}

Python code in kubemq/commandquery/response.py

def convert(self):
    return InnerResponse(
        ClientID=self.client_id or "",
        RequestID=self.request_id,
        ReplyChannel=self.reply_channel,
        Metadata=self.metadata or "",
        Body=self.body,
        CacheHit=self.cache_hit,
        Timestamp=int((self.timestamp - epoch).total_seconds()),    <-------------------------------
        Executed=self.executed,
        Error=self.error
    )
kubemq commented 1 year ago

We will look into it

Lior Nabat - Chat @ Spike [1y5bdb]

On February 13, 2023 at 14:47 GMT, Alessandro1996 @.***> wrote:

I'm using kubemq to communicate with other projects, using the CQRS pattern. My project's language is Python, the other projects' language is Java. The problem I encountered happens when I receive a response of a query and process it by means of kubemq-Python libary, while the response is built using kubemq-Java library.

Here is the error traceback: Grpc Exception in send_request:'[Errno 22] Invalid argument' Traceback (most recent call last): File "project\venv\lib\site-packages\kubemq\commandquery\lowlevel\initiator.py", line 68, in send_request return Response(inner_response) File "project\venv\lib\site-packages\kubemq\commandquery\response.py", line 60, in init self.timestamp = datetime.fromtimestamp(request.Timestamp) OSError: [Errno 22] Invalid argument Reproduction steps

Source of error

By debugging, the source is found to be in the different way of setting the timestamp, which defers between Java and Python library. The incompatibility can be seen in the following snippets (came from the cited libraries): Java works with timestamps in milliseconds, while Python works with timestamps in seconds

Java code in kubemq-java-sdk/src/main/java/io/kubemq/sdk/commandquery/Response.java Kubemq.Response Convert() { return Kubemq.Response.newBuilder() .setClientID(Optional.ofNullable(clientID).orElse("")) .setRequestID(requestID) .setReplyChannel(replyChannel) .setMetadata(Optional.ofNullable(metadata).orElse("")) .setBody(ByteString.copyFrom(body)) .setCacheHit(cacheHit) .setTimestamp(Converter.ToUnixTime(timestamp)) <------------------------------- .setExecuted(executed) .setError(Optional.ofNullable(error).orElse("")) .putAllTags(Optional.ofNullable(tags).orElse(new HashMap<String,String>())) .build(); }

where Converter.ToUnixTime(timestamp) is in kubemq-java-sdk/src/main/java/io/kubemq/sdk/tools/Converter.java public static long ToUnixTime(LocalDateTime timestamp) { return timestamp.atZone(TimeZone.getDefault().toZoneId()).toInstant().toEpochMilli(); }

Python code in kubemq/commandquery/response.py def convert(self): return InnerResponse( ClientID=self.client_id or "", RequestID=self.request_id, ReplyChannel=self.reply_channel, Metadata=self.metadata or "", Body=self.body, CacheHit=self.cache_hit, Timestamp=int((self.timestamp - epoch).total_seconds()), <------------------------------- Executed=self.executed, Error=self.error )

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you are subscribed to this thread.Message ID: @.***>