{"action":"created","issue":{"url":"https://api.github.com/repos/machinekit/machinekit/issues/114","labels_url":"https://api.github.com/repos/machinekit/machinekit/issues/114/labels{/name}","comments_url":"https://api.github.com/repos/machinekit/machinekit/issues/114/comments","events_url":"https://api.github.com/repos/machinekit/machinekit/issues/114/events","html_url":"https://github.com/machinekit/machinekit/issues/114","id":31344465,"number":114,"title":"Design error: command serials may collide","user":{"login":"mhaberler","id":901479,"avatar_url":"https://avatars.githubusercontent.com/u/901479?v=3","gravatar_id":"","url":"https://api.github.com/users/mhaberler","html_url":"https://github.com/mhaberler","followers_url":"https://api.github.com/users/mhaberler/followers","following_url":"https://api.github.com/users/mhaberler/following{/other_user}","gists_url":"https://api.github.com/users/mhaberler/gists{/gist_id}","starred_url":"https://api.github.com/users/mhaberler/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mhaberler/subscriptions","organizations_url":"https://api.github.com/users/mhaberler/orgs","repos_url":"https://api.github.com/users/mhaberler/repos","events_url":"https://api.github.com/users/mhaberler/events{/privacy}","received_events_url":"https://api.github.com/users/mhaberler/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/machinekit/machinekit/labels/problem","name":"problem","color":"fbca04"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":40,"created_at":"2014-04-11T17:10:32Z","updated_at":"2015-12-19T20:39:51Z","closed_at":null,"body":"Commands passed via NML typically have integer serial number for tracking status (received, being acted upon, completed, errored).\r\n\r\nThere is a fundamental design error: serial numbers are assigned on the originating side of a command. As soon as more than one command originator is active, this creates the danger of collisions, as NML has no identifier for an originator which could be used to make a submission ID unique (using a tuple (submitter, serial)). \r\n\r\nAn example for a hack around this issue is here: https://github.com/machinekit/machinekit/blob/master/src/emc/usr_intf/emcrsh.cc#L2842\r\n\r\nproblem: specify and implement a serial scheme which guarantees uniqueness."},"comment":{"url":"https://api.github.com/repos/machinekit/machinekit/issues/comments/166022504","html_url":"https://github.com/machinekit/machinekit/issues/114#issuecomment-166022504","issue_url":"https://api.github.com/repos/machinekit/machinekit/issues/114","id":166022504,"user":{"login":"mhaberler","id":901479,"avatar_url":"https://avatars.githubusercontent.com/u/901479?v=3","gravatar_id":"","url":"https://api.github.com/users/mhaberler","html_url":"https://github.com/mhaberler","followers_url":"https://api.github.com/users/mhaberler/followers","following_url":"https://api.github.com/users/mhaberler/following{/other_user}","gists_url":"https://api.github.com/users/mhaberler/gists{/gist_id}","starred_url":"https://api.github.com/users/mhaberler/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mhaberler/subscriptions","organizations_url":"https://api.github.com/users/mhaberler/orgs","repos_url":"https://api.github.com/users/mhaberler/repos","events_url":"https://api.github.com/users/mhaberler/events{/privacy}","received_events_url":"https://api.github.com/users/mhaberler/received_events","type":"User","site_admin":false},"created_at":"2015-12-19T20:39:51Z","updated_at":"2015-12-19T20:39:51Z","body":"hold those horses ;) not clear yet what the datastructure needed is since we have not fully thought through the problem yet; thinking aloud now:\r\n\r\n1. Acknowledgments - legacy NML. Simple if just one UI legacy channel. Just sets the echo_serial_number and status to whatever is being completed and write the status buffer. Broken if more than one UI connected, likely since serials go haywire in EMC_STAT.\r\n\r\n2. Acks - zeroMQ and NML in parallel: different ack mechanisms; on zeromq/ticket scheme, immediately replies with assigned ticket/RCS_RECEIVED then RCS_EXEC/RCS_DONE/RCS_ERROR acks as results come in. Note that we need to record the nature and origin of the current command so we can do the right thing according to channel - bump echo_serial.. on NML or reply on the _right_ dealer channel (assuming the general case - there are several zeromq UI's).\r\n\r\n3. A pending command is aborted by either input channel receiving an EMC_TASK_ABORT. Now both need acks (they could even come from different channels). That is currently not possible since we only record the last command and origin (which would be the abort, so the pending command being aborted really goes unacknowledged; we do not want that to avoid a UI deadlocking waiting for a serial/ticket in the ack which never shows up.\r\n\r\nTo address the above three, we need to record the _currently pending  command_ (but not the whole sequence) - and in case the abort comes in on the same channel as the pending command, the abort origin/type as well. On an abort we iterate the pending commands in ascending serial/ticket per channel, close those off, then ack the abort.\r\n\r\nOn top of this we have the current have-baked \"MDI Queuing\" behavior (looong thread back then on emc-developers). Here is the scenario:\r\n\r\n- example - you fire off two MDI commands _without_ waiting for RCS_DONE after the first one.\r\n- what happens is - both MDI commands are passed to the interpreter right away, and populate the canon queue (the mythical \"MDI queue\" is in fact the canon queue).\r\n- this just happens to work if the MDI commands have NO queue buster ops. If the first one has a queue buster, but the second MDI has not, the execution of the second MDI happily tramples over the interpreter state of the first command (which might still be waiting for the queue to finish, execute the queue buster and continue\r\n- the whole thing is a bug redressed as a feature. it happens because task blindly calls the interpreter read/exec functions without regard what is still going on.\r\n\r\nJust saying we need to keep this one in mind. The more I think of it though - I guess #106 will take care of this as the interpreter becomes master of its main loop, and will be fed through a queue (another dealer/router pair) between task and interpreter - it will just not start executing the second MDI before the first one finishes. So then we'll have a proper queueing behavior of the interpreter as a result of closing off #106. Once the interpreter dequeues a command she'll ack the command, and task can send an RCS_EXEC update to the originator.\r\n\r\nAnyway - the simplest and most general tracking mechanism is likely a list. This is how it would work:\r\n\r\n- every command coming in is recorded in this list, by appending, with: channel, serial or ticket, status.\r\n- status change of a ticket or serial: search list for match of serial/ticket and channel. Record status; or if status is RCS_DONE, delete the list item after sending update in proper channel/mechanism.\r\n- abort: add the abort command. Execute it. when done, complete the whole list of pending commands starting oldest first, acking with proper channel/mechanism.\r\n\r\nTo verify we got things right, a periodic scan on task idle must meet an empty command list. If not, we must have missed an ack which is an error.\r\n\r\n\r\n\r\n\r\n"}}