tags 717832 +pending
thanks
Hallo,
* Julian Andres Klode [Thu, Jul 25 2013, 03:52:34PM]:
> Package: apt-cacher-ng
> Severity: normal
>
> If many files are fetched -- for example, during an
> apt-get dist-upgrade -- apt-cacher-ng will respond
> multiple times with a connection timeout. This is
> a bit annoying, as I have to re-run my upgrade
> scripts multiple times to fetch all files.
Confirmed, found a bug that is most likely responsible for not handling
timed-out connection state correctly (the surrounding code is well
prepared for this state it's just not passed correctly).
In the Wheezy version, disabling connection reusing might help a little
bit but there are still chances that it will happen. A fix will appear
ASAP or use this little patch in the meantime.
> This bug already exists since a few years, but I
> did not report it earlier (I don't know why).
Yeah, too bad. It was quite easy to track down unlike some other issue
found in the Wheezy version.
Regards,
Eduard.
Index: source/dlcon.cc
===================================================================
--- source/dlcon.cc (.../tags/0.7.14-1) (Revision 4104)
+++ source/dlcon.cc (.../trunk) (Revision 4104)
@@ -527,6 +527,14 @@
return EFLAG_JOB_BROKEN;
}
+ inline bool IsRecoverableState()
+ {
+ return (m_DlState == STATE_GETHEADER || m_DlState == STATE_REGETHEADER);
+ // XXX: In theory, could also easily recover from STATE_FINISH but that's
+ // unlikely to happen
+
+ }
+
private:
// not to be copied ever
tDlJob(const tDlJob&);
@@ -707,7 +715,13 @@
dbgline;
sErrorMsg = "500 Connection timeout";
// was there anything to do at all?
- return inpipe.empty() ? HINT_SWITCH : (HINT_DISCON|EFLAG_JOB_BROKEN);
+ if(inpipe.empty())
+ return HINT_SWITCH;
+
+ if(inpipe.front()->IsRecoverableState())
+ return EFLAG_LOST_CON;
+ else
+ return (HINT_DISCON|EFLAG_JOB_BROKEN);
}
if (FD_ISSET(m_wakepipe[0], &rfds))
@@ -916,17 +930,13 @@
{
setLockGuard;
LOG("New jobs: " << m_qNewjobs.size());
- /* This evil code is left behind from the previous generation, now it breaks the
- * internal logics of the HTTP state machine by externally manipulating its state.
- * There is no need for this hack either because the pipeline cleanup after a sudden
- * interruption is handled explicitly elsewhere, see CleanRunning calls.
+
if(m_bStopASAP)
{
- // ordered to stop but someone might rely on the running job. Keep it running,
- // if the last user disappears and will cause the termination RSN
- if(inpipe.size()>1)
- inpipe.erase(++(inpipe.begin()), inpipe.end());
-
+ /* The no-more-users checking logic will purge orphaned items from the inpipe
+ * queue. When it's dirty, it will be have closed in the ExchangeData() handling
+ * but if not then it can be assumed to be clean and reusable.
+ */
if(inpipe.empty())
{
if(con)
@@ -934,8 +944,8 @@
return;
}
}
- */
+
if(m_qNewjobs.empty())
goto go_select; // parent will notify RSN