{"payload":{"feedbackUrl":"https://github.com/orgs/community/discussions/53140","repo":{"id":2444141,"defaultBranch":"main","name":"ruby-mqtt","ownerLogin":"njh","currentUserCanPush":false,"isFork":false,"isEmpty":false,"createdAt":"2011-09-23T13:41:09.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/38734?v=4","public":true,"private":false,"isOrgOwned":false},"refInfo":{"name":"","listCacheKey":"v0:1677802537.116181","currentOid":""},"activityList":{"items":[{"before":"75c70e6a142472db639a3f9dd8faf2e3f4a9af06","after":"b2e48d05f48919949c1c23f6fd5b9f05b6265a82","ref":"refs/heads/main","pushedAt":"2024-05-19T07:45:47.000Z","pushType":"pr_merge","commitsCount":1,"pusher":{"login":"njh","name":"Nicholas Humfrey","path":"/njh","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/38734?s=80&v=4"},"commit":{"message":"Handle instantaneous and unsolicited PUBACKs (#158)\n\nPrior to this commit, it was possible to crash the read thread\r\nby sending a PUBACK with an unexpected ID, e.g. an ID the client\r\nhad not used before, or had already deleted the queue for.\r\nThese packets will now simple be ignored.\r\n\r\nFurthermore, with QoS 1 or 2, the PUBACK queue for a packet\r\nwas only created _after_ the packet had already been published.\r\nIf the PUBACK arrived within this tiny gap, the read thread would crash.\r\nWe fix this by creating the queue before starting to publish.","shortMessageHtmlLink":"Handle instantaneous and unsolicited PUBACKs (#158)"}},{"before":"52ef5ff92650786a7b6afe864d85484ef190baea","after":"75c70e6a142472db639a3f9dd8faf2e3f4a9af06","ref":"refs/heads/main","pushedAt":"2024-04-03T00:11:54.000Z","pushType":"pr_merge","commitsCount":1,"pusher":{"login":"njh","name":"Nicholas Humfrey","path":"/njh","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/38734?s=80&v=4"},"commit":{"message":"tls hostname verification (#125)\n\nCo-authored-by: Uwe Kubosch ","shortMessageHtmlLink":"tls hostname verification (#125)"}},{"before":"0b967ff6177cce139d6054df8af2ee6ea793a5db","after":"52ef5ff92650786a7b6afe864d85484ef190baea","ref":"refs/heads/main","pushedAt":"2024-04-02T23:09:39.000Z","pushType":"pr_merge","commitsCount":1,"pusher":{"login":"njh","name":"Nicholas Humfrey","path":"/njh","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/38734?s=80&v=4"},"commit":{"message":"supporting private keys other than `RSA` (#148)\n\n* also fixes `File` leakage in `MQTT::Client#key_file=`\r\n\r\nFixes #147","shortMessageHtmlLink":"supporting private keys other than RSA (#148)"}},{"before":"271ee631f128e66732ece935e752f13970d4267b","after":"0b967ff6177cce139d6054df8af2ee6ea793a5db","ref":"refs/heads/main","pushedAt":"2024-04-02T22:53:56.000Z","pushType":"pr_merge","commitsCount":1,"pusher":{"login":"njh","name":"Nicholas Humfrey","path":"/njh","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/38734?s=80&v=4"},"commit":{"message":"Prevent deadlock due to system call error (#159)\n\nThe MQTT client runs in the main thread which consumes incoming\r\nMQTT messages from a `Thread::Queue` called `@read_queue`.\r\nThis queue is fed by the `@read_thread`, a child thread which\r\nreads from a socket in an infinite loop.\r\n\r\nWe noticed that our application stopped processing incoming\r\nMQTT messages, but did not seem to exit or throw an exception either.\r\nUpon inspecting the logs, we saw that the `@read_thread` had crashed\r\ndue to an unhandled `Errno::ECONNRESET` while reading from the socket.\r\nThis had the consuming thread then sleep forever while waiting for\r\nnew meassages on the `@read_queue`.\r\n\r\nIt turned out that the `MQTT::Client#receive_packet` method had\r\nappropriate error handling in place\r\n\r\n```ruby\r\ndef receive_packet\r\n # ...\r\nrescue Exception\r\n # ...\r\nend\r\n```\r\n\r\nbut this did not rescue `Errno::ECONNRESET` even though `Exception`\r\nis at the top of the hierarchy of\r\n[Ruby's built-in exception classes][builtin-exceptions].\r\n\r\nThe root cause was that the library also defines a class `MQTT::Exception`\r\nand in the context of `#receive_packet` the constant `Exception`\r\nrefers only to `MQTT::Exception` (which does not cover `Errno::ECONNRESET`)\r\nwhere it actually should rescue any subclass of `::Exception`.\r\n\r\n[builtin-exceptions]: https://docs.ruby-lang.org/en/3.2/Exception.html#class-Exception-label-Built-In+Exception+Classes","shortMessageHtmlLink":"Prevent deadlock due to system call error (#159)"}}],"hasNextPage":false,"hasPreviousPage":false,"activityType":"all","actor":null,"timePeriod":"all","sort":"DESC","perPage":30,"cursor":"djE6ks8AAAAETfZPQwA","startCursor":null,"endCursor":null}},"title":"Activity ยท njh/ruby-mqtt"}