Remove support for multi command expansion in sending phase

We won't support this after all, it's too much of a headache with
regards to the sending queue. Pausing takes longer, cancelling takes
longer, resends get more complicated and so on.

Command expansion in the queuing phase needs to suffice.
This commit is contained in:
Gina Häußge 2017-07-17 16:05:15 +02:00
parent a50db4b08e
commit ee2d644239
2 changed files with 24 additions and 20 deletions

View file

@ -426,7 +426,7 @@ This describes actually four hooks:
* ``None``: Don't change anything. Note that Python functions will also automatically return ``None`` if
an empty ``return`` statement is used or just nothing is returned explicitly from the handler. Hence, the following
examples are all falling into this category:
examples are all falling into this category and equivalent:
.. code-block:: python
@ -451,21 +451,24 @@ This describes actually four hooks:
should use this option.
* A 2-tuple consisting of a rewritten version of the ``cmd`` and the ``cmd_type``, e.g. ``return "M105", "temperature_poll"``.
Handlers which wish to rewrite both the command and the command type should use this option.
* A list of any of the above to allow for expanding one command into
* **"queuing" phase only**: A list of any of the above to allow for expanding one command into
many. The following example shows how any queued command could be turned into a sequence of a temperature query,
line number reset, display of the ``gcode`` on the printer's display and finally the actual command (this example
does not make a lot of sense to be quite honest):
.. code-block:: python
def rewrite_foo(self, comm_instance, phase, cmd, cmd_type, gcode, *args, **kwargs):
if gcode or not cmd.startswith("@foo"):
return
def rewrite_foo(self, comm_instance, phase, cmd, cmd_type, gcode, *args, **kwargs):
if gcode or not cmd.startswith("@foo"):
return
return [("M105", "temperature_poll"),
("M110",),
"M117 echo foo: {}".format(cmd)]
return [("M105", "temperature_poll"), # 2-tuple, command & command type
("M110",), # 1-tuple, just the command
"M117 echo foo: {}".format(cmd)] # string, just the command
__plugin_hooks__ = {
"octoprint.comm.protocol.gcode.queuing": rewrite_foo
}
Note: Only one command of a given ``cmd_type`` (other than None) may be queued at a time. Trying to rewrite the ``cmd_type``
to one already in the queue will give an error.

View file

@ -2255,18 +2255,13 @@ class MachineCom(object):
# and now let's fetch the next item from the queue
continue
if len(results) > 1:
with self._sendingLock:
# prepend reversed (so order gets restored)
to_prepend = reversed(results[1:-1])
for m in to_prepend:
try:
self._send_queue.prepend((m[0], None, m[1], on_sent, True), item_type=m[1])
on_sent = None
except TypeAlreadyInQueue:
pass
# we explicitly throw away plugin hook results that try
# to perform command expansion in the sending/sent phase,
# so "results" really should only have more than one entry
# at this point if our core code contains a bug
assert len(results) == 1
# we only actually send the first entry here
# we only use the first (and only!) entry here
command, _, gcode, subcode = results[0]
if command.strip() == "":
@ -2341,7 +2336,13 @@ class MachineCom(object):
self._logger.exception("Error while processing hook {name} for phase {phase} and command {command}:".format(**locals()))
else:
normalized = _normalize_command_handler_result(command, command_type, gcode, subcode, hook_results)
new_results += normalized
# make sure we don't allow multi entry results in anything but the queuing phase
if not phase in ("queuing",) and len(normalized) > 1:
self._logger.error("Error while processing hook {name} for phase {phase} and command {command}: Hook returned multi-entry result for phase {phase} and command {command}. That's not supported, if you need to do multi expansion of commands you need to do this in the queuing phase. Ignoring hook result and sending command as-is.".format(**locals()))
new_results.append((command, command_type, gcode, subcode))
else:
new_results += normalized
if not new_results:
# hook handler returned None or empty list for all commands, so we'll stop here and return a full out empty result
return []