Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge branch 'staging/maintenance' into maintenance
  • Loading branch information
foosel committed Jul 16, 2018
2 parents 9559f09 + 460481c commit 5cf02ac
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 26 deletions.
6 changes: 3 additions & 3 deletions .versioneer-lookup
Expand Up @@ -24,10 +24,10 @@ maintenance 1.3.10 fdf0f75ffa5731fee406c6e761e84a9d2b47aa43 pep440-dev
fix/.* 1.3.10 fdf0f75ffa5731fee406c6e761e84a9d2b47aa43 pep440-dev
improve/.* 1.3.10 fdf0f75ffa5731fee406c6e761e84a9d2b47aa43 pep440-dev

# staging/maintenance is currently the branch for preparation of 1.3.9rc2
# staging/maintenance is currently the branch for preparation of 1.3.9rc4
# so is regressionfix/...
staging/maintenance 1.3.9rc3 fd94fc94a09dd91deeb2f59a6b3b00b37eb1f145 pep440-dev
regressionfix/.* 1.3.9rc3 fd94fc94a09dd91deeb2f59a6b3b00b37eb1f145 pep440-dev
staging/maintenance 1.3.9rc4 2806676707020b270097876d6189d3c484dd47b8 pep440-dev
regressionfix/.* 1.3.9rc4 2806676707020b270097876d6189d3c484dd47b8 pep440-dev

# every other branch is a development branch and thus gets resolved to 1.4.0-dev for now
.* 1.4.0 7f5d03d0549bcbd26f40e7e4a3297ea5204fb1cc pep440-dev
16 changes: 16 additions & 0 deletions CHANGELOG.md
@@ -1,11 +1,27 @@
# OctoPrint Changelog

## 1.3.9rc3 (2018-07-16)

### Improvements

* Fix resend and timeout handling during an active `job_on_hold`.

### Bug fixes

* [#2677](https://github.com/foosel/OctoPrint/issues/2677) (regression) - Fix a deadlock when `job_on_hold` is utilized (causing issues at least with Octolapse)
* [#2719](https://github.com/foosel/OctoPrint/issues/2719) (regression) - Fix live print time estimation

### More information

* [Commits](https://github.com/foosel/OctoPrint/compare/1.3.9rc2...1.3.9rc3)

## 1.3.9rc2 (2018-07-06)

### Improvements

* Add sanity check for disabled plugin list (see also [#2687 (comment)](https://github.com/foosel/OctoPrint/issues/2687#issuecomment-399797596)).
* Improve logging of exceptions triggered inside the state update worker (see also [#2715](https://github.com/foosel/OctoPrint/issues/2715)).
* Workaround for a potential `pip` issue when updating components through the Software Update plugin.

### Bug fixes

Expand Down
3 changes: 2 additions & 1 deletion SUPPORTERS.md
Expand Up @@ -28,6 +28,7 @@ thanks to everyone who contributed!
* Jeff Renfer
* Jefferson Hunt
* Jeremiah Avery
* Joseph Payne
* Josh Daniels
* Joshua Wills
* Justin Kaufman
Expand Down Expand Up @@ -59,4 +60,4 @@ thanks to everyone who contributed!
* Timothy D Hoogland
* Trent Shumay

and 1332 more wonderful people pledging on the [Patreon campaign](https://patreon.com/foosel)!
and 1333 more wonderful people pledging on the [Patreon campaign](https://patreon.com/foosel)!
55 changes: 33 additions & 22 deletions src/octoprint/util/comm.py
Expand Up @@ -780,6 +780,9 @@ def job_on_hold(self):
return self._job_on_hold.counter > 0

def set_job_on_hold(self, value, blocking=True):
trigger = False

# don't run any locking code beyond this...
if not self._job_on_hold.acquire(blocking=blocking):
return False

Expand All @@ -789,10 +792,14 @@ def set_job_on_hold(self, value, blocking=True):
else:
self._job_on_hold.clear()
if self._job_on_hold.counter == 0:
self._continue_sending()
trigger = True
finally:
self._job_on_hold.release()

# locking code is now safe to run again
if trigger:
self._continue_sending()

return True

def close(self, is_error=False, wait=True, timeout=10.0, *args, **kwargs):
Expand Down Expand Up @@ -1490,11 +1497,13 @@ def _monitor(self):
self.sayHello()

while self._monitoring_active:
now = time.time()
try:
line = self._readline()
if line is None:
break

now = time.time()

if line.strip() is not "":
self._consecutive_timeouts = 0
self._timeout = get_new_timeout("communicationBusy" if self._busy_protocol_detected else "communication", self._timeout_intervals)
Expand Down Expand Up @@ -1609,7 +1618,7 @@ def convert_line(line):
handled = False

# process oks
if line.startswith("ok") or (self.isPrinting() and not self.job_on_hold and supportWait and line == "wait"):
if line.startswith("ok") or (self.isPrinting() and supportWait and line == "wait"):
# ok only considered handled if it's alone on the line, might be
# a response to an M105 or an M114
self._handle_ok()
Expand All @@ -1623,11 +1632,11 @@ def convert_line(line):
handled = True

# process timeouts
elif ((line == "" and now > self._timeout) or (self.isPrinting()
and not self.isSdPrinting()
and not self.job_on_hold
and not self._long_running_command
and not self._heating and now > self._ok_timeout)) \
elif ((line == "" and now >= self._timeout) or (self.isPrinting()
and not self.isSdPrinting()
and (not self.job_on_hold or self._resendActive)
and not self._long_running_command
and not self._heating and now >= self._ok_timeout)) \
and (not self._blockWhileDwelling or not self._dwelling_until or now > self._dwelling_until):
# We have two timeout variants:
#
Expand Down Expand Up @@ -2042,29 +2051,24 @@ def _handle_ok(self):
if not self._state in self.OPERATIONAL_STATES:
return

# process queues ongoing resend requests and queues if we are operational

with self._sendingLock: # prevent concurrency due to resend_ok_timers
if self._resendDelta is not None:
self._resendNextCommand()
else:
self._resendActive = False
self._continue_sending()
if self._resendDelta is not None and self._resendNextCommand():
# we processed a resend request and are done here
return

return
# continue with our queues and the job
self._resendActive = False
self._continue_sending()

def _handle_timeout(self):
if self._state not in (self.STATE_PRINTING,
self.STATE_PAUSED,
self.STATE_OPERATIONAL):
if self._state not in self.OPERATIONAL_STATES:
return

general_message = "Configure long running commands or increase communication timeout if that happens regularly on specific commands or long moves."

# figure out which consecutive timeout maximum we have to use
if self._long_running_command:
consecutive_max = self._consecutive_timeout_maximums.get("long", 0)
elif self._state in (self.STATE_PRINTING,):
elif self._state in self.PRINTING_STATES:
consecutive_max = self._consecutive_timeout_maximums.get("printing", 0)
else:
consecutive_max = self._consecutive_timeout_maximums.get("idle", 0)
Expand Down Expand Up @@ -2100,7 +2104,7 @@ def _handle_timeout(self):
# long running command active, ignore timeout
self._logger.debug("Ran into a communication timeout, but a command known to be a long runner is currently active")

elif self._state in (self.STATE_PRINTING, self.STATE_PAUSED):
elif self._state in self.PRINTING_STATES + (self.STATE_PAUSED,):
# printing, try to tickle the printer
message = "Communication timeout while printing, trying to trigger response from printer."
self._logger.info(message)
Expand Down Expand Up @@ -2755,13 +2759,20 @@ def _resendNextCommand(self, again=False):
self._resendDelta = 0
self._resendDelta += 1

elif self._resendDelta is None:
# we might enter this twice in quick succession if we get triggered by the
# resend_ok_timer, so make sure that resendDelta is actually still set (see #2632)
return False

cmd = self._lastLines[-self._resendDelta]
lineNumber = self._currentLine - self._resendDelta

result = self._enqueue_for_sending(cmd, linenumber=lineNumber, resend=True)

self._resendDelta -= 1
if self._resendDelta <= 0:
# reset everything BUT the resendActive flag - that will have to stay active until we receive
# our next ok!
self._resendDelta = None
self._lastResendNumber = None
self._currentResendCount = 0
Expand Down

0 comments on commit 5cf02ac

Please sign in to comment.