Closed tenderlove closed 4 years ago
Awesome, that is great, thanks!
I hated that there was a sleep
in the code but had forgotten about it when those performance issues were brought up.
I will get those old/broken versions of ruby removed from Travis, then get this PR merged.
@njh 🙇🏻♀️ thank you for making this library!
While I was thinking about this, I realized I've kind of broken the timeout code. We need to add this line:
diff --git a/lib/mqtt/client.rb b/lib/mqtt/client.rb
index 707f932..e6e9884 100644
--- a/lib/mqtt/client.rb
+++ b/lib/mqtt/client.rb
@@ -459,6 +459,7 @@ module MQTT
def receive_packet
# Poll socket - is there data waiting?
result = IO.select([@socket], [], [], SELECT_TIMEOUT)
+ handle_timeouts
unless result.nil?
# Yes - read in the packet
packet = MQTT::Packet.read(@socket)
I'm trying to figure out how to write a test for it though. It doesn't seem like there's a way to get the read thread to run in the test framework.
@njh I added a test for the timeout, but the test is extremely hacky :( It does ensure we hit our timeouts though.
Sorry, I completely forgot to merge this. Done now! Thank you very much for this contribution.
This commit changes the
publish
method to use a queue to wait for Puback packets rather than polling a hash. Every time the read loop gets data or a timeout fromIO.select
, it will send a message to everyone waiting for aPuback
packet. If the we're within the deadline, then the loop executes again, if we got a packet, we'll return the packet, and if we're outside the deadline, a-1
is returned.This upside is that this patch speeds up the publish method by over 100x. Here is the benchmark:
Before this patch:
After this patch:
The downside is that the timeout isn't exact. Since
IO.select
times out every0.5
seconds (according to theSELECT_TIMEOUT
constant), the deadline in thepublish
method could be missed by that amount of time.Refs #115