{"record":{"id":"058829e47d2d2d2b","repo":"XX-net/XX-Net","slug":"url-in-downloading-s","errorCode":null,"errorMessage":"url in downloading, %s","messagePattern":"url in downloading, (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"code/default/launcher/update_from_github.py","lineNumber":92,"sourceCode":"            \"host\": \"127.0.0.1\",\n            \"port\": 8086,\n            \"user\": None,\n            \"pass\": None\n        }, timeout=timeout, cert=cert)\n\n    res = client.request(\"GET\", url, read_payload=False)\n    return res\n\n\ndef download_file(url, filename):\n    if url not in progress:\n        progress[url] = {}\n        progress[url][\"status\"] = \"downloading\"\n        progress[url][\"size\"] = 1\n        progress[url][\"downloaded\"] = 0\n    else:\n        if progress[url][\"status\"] == \"downloading\":\n            xlog.warn(\"url in downloading, %s\", url)\n            return False\n\n    for i in range(0, 2):\n        try:\n            xlog.info(\"download %s to %s, retry:%d\", url, filename, i)\n            req = request(url, i, timeout=120)\n            if not req:\n                continue\n\n            start_time = time.time()\n            timeout = 300\n\n            if req.chunked:\n                # don't known the file size, set to large for show the progress\n                progress[url][\"size\"] = 20 * 1024 * 1024\n\n                downloaded = 0\n                with open(filename, 'wb') as fp:","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/XX-net/XX-Net/blob/cfa5bc17b67676e467f37ec50766127e0ab5f0aa/code/default/launcher/update_from_github.py#L74-L110","documentation":"update_from_github.download_file keeps a global progress dict keyed by URL; if an entry exists with status 'downloading', a concurrent call for the same URL is rejected with this warning and returns False, to prevent two threads writing the same file.","triggerScenarios":"Two callers invoke download_file with the same URL concurrently — e.g. get_github_versions and download_overwrite_new_version racing, or a user double-triggering update while a download is in flight; also stale 'downloading' state left by a crashed thread.","commonSituations":"Double-clicking update / overlapping update checks in the web UI; a previous download thread died without resetting progress[url]['status'], permanently blocking that URL.","solutions":["Wait for the in-flight download to finish and retry the operation once","If it never clears (stale state after a crash), restart the launcher to reset the progress dict","Avoid triggering update operations concurrently from the UI","Code-level: reset progress[url] status in a finally block so failures don't leave 'downloading' state"],"exampleFix":"// before (in update_from_github.download_file)\nprogress[url][\"status\"] = \"downloading\"\ntry:\n    do_download()\nfinally:\n    progress.pop(url, None)\n\n// concept: always clear the per-url lock state so a crashed download does not block the next attempt","handlingStrategy":"validation","validationCode":"from update_from_github import progress\ndef url_free(url):\n    return progress.get(url, {}).get('status') != 'downloading'\nassert url_free(url), 'download already in flight; wait or restart'","typeGuard":null,"tryCatchPattern":"try:\n    ok = download_file(url, path)\n    if not ok and progress.get(url,{}).get('status') == 'downloading':\n        wait_for_download(url)  # another thread owns it\nexcept Exception as e:\n    log.warning('download error: %r', e)\n    progress.pop(url, None)","preventionTips":["Avoid triggering concurrent updates of the same module","Restart the launcher if a URL seems permanently 'downloading' (stale state)","Wrap download state updates in try/finally to always reset status"],"tags":["concurrency","download","dedup-lock"],"backgroundTag":"concurrent-duplicate-request","analyzedSha":"cfa5bc17b67676e467f37ec50766127e0ab5f0aa","analyzedAt":"2026-08-27T19:28:28.225Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}