Re: Making Python Script Exit Completely with One Ctrl+C
Hongyi Zhao via curl-users <[email protected]>
| Newsgroups | gmane.comp.web.curl.general |
|---|---|
| Message-ID | <CAGP6POLWWm_uw1oki94E0_Cy6hPYFQz1p=-CTR-X-8+wOMWn3Q@mail.gmail.com> |
On Sun, Dec 10, 2023 at 10:58 AM Dan Fandrich via curl-users <[email protected]> wrote: > > On Sat, Dec 09, 2023 at 01:51:13PM +0800, Hongyi Zhao via curl-users wrote: > > Now, I try to compare the manually computed average speed and the one > > given by pycurl in the attached script, but the latter always is 0: > [...] > > try: > > c.perform() > > py_speed = c.getinfo(pycurl.SPEED_DOWNLOAD) / 1024 > > except pycurl.error as e: > > pass > > finally: > > c.close() > > Are you sure c.perform() isn't raising an exception? That would leave py_speed > as 0, as you are observing. Hiding exceptions like this can cause no end of > problems when things go wrong. The attached script does the trick: (datasci) werner@X10DAi:~/Desktop$ python rev-3.6.py Testing Proxy: SG_ssr_futeapbquf5m.nodelist.club_1453_018d83c677e05e71f172014fc3f45e39 Current Speed: 21.04 kB/s Current Speed: 3726.05 kB/s Error occurred while performing curl: (28, 'Operation timed out after 5000 milliseconds with 29650632 out of 1073741824 bytes received') PycURL Speed: 5791.21 kB/s Average Speed: 5790.76 kB/s Testing Proxy: HK_ssr_wo8o8npg4fny.nodelist.club_1303_b5bf85111d0f51c517ec7302d3f33ce1 Current Speed: 828.35 kB/s Current Speed: 5367.13 kB/s Error occurred while performing curl: (28, 'Operation timed out after 5000 milliseconds with 33954720 out of 1073741824 bytes received') PycURL Speed: 6631.92 kB/s Average Speed: 6631.49 kB/s Testing Proxy: SG_ssr_futeapbquf5m.nodelist.club_1354_ddfba110eddfdb7037f389e9b5917477 ^CKeyboardInterrupt at line 72 But I still cannot figure out how to achieve the same purpose with the following methods: 1. Using the following method suggested by you: You'll probably have to block SIGINT before calling calling into pycurl, then unblocking in the progress callback to check it, e.g. ... signal.pthread_sigmask(signal.SIG_BLOCK, [signal.SIGINT]) c.perform() signal.pthread_sigmask(signal.SIG_UNBLOCK, [signal.SIGINT]) ... def progress(...): try: signal.pthread_sigmask(signal.SIG_UNBLOCK, [signal.SIGINT]) except KeyboardInterrupt: print('interrupted!') return 1 finally: signal.pthread_sigmask(signal.SIG_BLOCK, [signal.SIGINT]) 2. Using a pure try-expect-based method. Regards, Zhao > -- > Unsubscribe: https://lists.haxx.se/mailman/listinfo/curl-users > Etiquette: https://curl.se/mail/etiquette.html -- Unsubscribe: https://lists.haxx.se/mailman/listinfo/curl-users Etiquette: https://curl.se/mail/etiquette.html
rev-3.6.py
(text/x-python, 2.8 KB)
import subprocess
import time
import pycurl
from io import BytesIO
import sys
import signal
def sigint_handler(signal, frame):
print(f"KeyboardInterrupt at line {frame.f_lineno}")
sys.exit(0)
signal.signal(signal.SIGINT, sigint_handler)
def fetch_proxies():
command = 'echo "show stat" | sudo socat stdio /var/run/haproxy.sock 2>/dev/null | awk -F, \'$1=="socks5" && !($2~/^(FRONTEND|BACKEND)$/) {print $2,$74}\''
try:
process = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
output, error = process.communicate()
except Exception as e:
print("Error occurred while executing shell command: ", e)
return {}
result_dict = {}
if error is not None:
print("Error occurred while getting proxies status: ", error.decode('utf-8'))
lines = output.decode('utf-8').split('\n')
for line in lines:
if line and len(line.split(' ')) == 2:
key_value = line.split(' ')
result_dict[key_value[0]] = key_value[1]
return result_dict
def test_proxy(proxy, url):
global last_calc_time, download_start_time, total_downloaded_data
buffer = BytesIO()
c = pycurl.Curl()
c.setopt(pycurl.URL, url)
c.setopt(pycurl.WRITEDATA, buffer)
c.setopt(pycurl.PROXY, proxy)
c.setopt(pycurl.PROXYTYPE, pycurl.PROXYTYPE_SOCKS5_HOSTNAME)
c.setopt(pycurl.NOPROGRESS, False)
c.setopt(pycurl.XFERINFOFUNCTION, progress)
c.setopt(pycurl.TIMEOUT, 5)
download_start_time = time.time()
last_calc_time = download_start_time
total_downloaded_data = 0
py_speed = 0
try:
c.perform()
total_downloaded_data = c.getinfo(pycurl.SIZE_DOWNLOAD)
except pycurl.error as e:
print("Error occurred while performing curl: ", e)
finally:
py_speed = c.getinfo(pycurl.SPEED_DOWNLOAD) / 1024
c.close()
elapsed_time = time.time() - download_start_time
average_speed = total_downloaded_data / elapsed_time / 1024
print(f"PycURL Speed: {py_speed:.2f} kB/s")
return average_speed
def progress(download_t, download_d, upload_t, upload_d):
global last_calc_time, download_start_time, total_downloaded_data
current_time = time.time()
if current_time - last_calc_time >= 2:
elapsed_time = current_time - download_start_time
current_speed = download_d / elapsed_time / 1024
print(f"Current Speed: {current_speed:.2f} kB/s")
last_calc_time = current_time
total_downloaded_data = download_d
return 0
proxy_data = fetch_proxies()
if not proxy_data:
print("No proxy data found.")
sys.exit(1)
url = "http://ipv4.download.thinkbroadband.com/1GB.zip"
for key, value in proxy_data.items():
print(f"Testing Proxy: {key}")
average_speed = test_proxy(value, url)
print(f"Average Speed: {average_speed:.2f} kB/s")