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 <CAGP6PO+c_XJVtByVV90fh-S8fR6H7ZgcdjOjjsCgzTt6=9Qiwg@mail.gmail.com>
On Sat, Dec 9, 2023 at 9:37 AM Hongyi Zhao <[email protected]> wrote:
>
> On Fri, Dec 8, 2023 at 10:44 AM Dan Fandrich via curl-users
> <[email protected]> wrote:
> >
> > On Fri, Dec 08, 2023 at 09:56:44AM +0800, Hongyi Zhao via curl-users wrote:
> > > I tried the following method but in vain:
> > [...]
> > >     try:
> > >         pass
> > >     except KeyboardInterrupt:
> > >         kb_interrupt = True
> >
> > This won't accomplish anything because "pass" will never raise an exception.
> > I have a feeling that even putting the entire contents of the progress callback
> > into a try/except block won't even help; I suspect the exception is raised the
> > moment the Python interpreter is returned to by pycurl while calling that
> > callback, which is before even that point.
> >
> > 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])
> >
> > or just set your own SIGINT handler that sets a flag (kb_interrupt), then check
> > that flag in the progress callback and return an error if it's set.
>
> I tried using the first method of your tips. It works, but the
> calculated *Average Speed* is too high, as shown below:
>
> (datasci) werner@X10DAi:~/Desktop$ python callback-SIGINT.py
> Proxy: SG_ssr_futeapbquf5m.nodelist.club_1453_018d83c677e05e71f172014fc3f45e39
> Current Speed: 1371.74 kB/s
> Current Speed: 6565.90 kB/s
> Average Speed: 7552.72 kB/s
> Proxy: HK_ssr_wo8o8npg4fny.nodelist.club_1303_b5bf85111d0f51c517ec7302d3f33ce1
> Current Speed: 1252.55 kB/s
> Current Speed: 7461.93 kB/s
> Average Speed: 8807.27 kB/s
> Proxy: SG_ssr_futeapbquf5m.nodelist.club_1354_ddfba110eddfdb7037f389e9b5917477
> Current Speed: 3081.76 kB/s
> Current Speed: 9351.58 kB/s
> Average Speed: 10745.23 kB/s
> Proxy: HK_ssr_fwqvvo60u1mj.nodelist.club_1423_dba3b0996744e7b82eae7634626a5ba9
> ^Cinterrupted!
> Average Speed: 156.74 kB/s
> Proxy: SG_ssr_futeapbquf5m.nodelist.club_1356_8ce27b1301fcbcb77cc5abb28cb127a6
> Script terminated by user. Exiting.
>
> I'm not sure how to fix this problem. Attached please find the test script.

I tried another method which also had the same problem:

(datasci) werner@X10DAi:~/Desktop$ python rev-2.py
Proxy: SG_ssr_futeapbquf5m.nodelist.club_1453_018d83c677e05e71f172014fc3f45e39
Current Speed: 664.56 kB/s
Current Speed: 7691.08 kB/s
Average Speed: 9403.12 kB/s
Proxy: HK_ssr_wo8o8npg4fny.nodelist.club_1303_b5bf85111d0f51c517ec7302d3f33ce1
Current Speed: 950.39 kB/s
Current Speed: 6146.08 kB/s
Average Speed: 7297.46 kB/s
Proxy: SG_ssr_futeapbquf5m.nodelist.club_1354_ddfba110eddfdb7037f389e9b5917477
^CTraceback (most recent call last):
  File "/home/werner/Desktop/rev-2.py", line 60, in progress
    def progress(download_t, download_d, upload_t, upload_d):

KeyboardInterrupt


> 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-2.py (text/x-python, 2.5 KB)
import subprocess
import time
import pycurl
from io import BytesIO 
import sys

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}\''
    process = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
    output, error = process.communicate()

    result_dict = {}  # Initialize default empty dictionary

    if error is not None:
        return result_dict  # Return the empty dictionary in case of error

    lines = output.decode('utf-8').split('\n')

    for line in lines:
        if line != "":
            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

    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

    try:
        c.perform()
    except pycurl.error as e:
        #print(f'An error occurred: {e}')
        # 输出异常的错误代码和描述
        #print(f'Error code: {e.args[0]}')
        #print(f'Error message: {e.args[1]}')
        if e.args[0]==42:
            #print("Script interrupted by user. Exiting During perform pycurl.")
            sys.exit(0)  # 立即退出程序
        else:
            pass

    average_speed = c.getinfo(pycurl.SPEED_DOWNLOAD) / 1024
    return average_speed

def progress(download_t, download_d, upload_t, upload_d):
    global last_calc_time, download_start_time
    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

proxy_data = fetch_proxies()
url = "http://ipv4.download.thinkbroadband.com/1GB.zip"

for key, value in proxy_data.items():
    print(f"Proxy: {key}")
    try:
        average_speed = test_proxy(value, url)
        print(f"Average Speed: {average_speed:.2f} kB/s")
    except KeyboardInterrupt:
        print("Script interrupted by user. Exiting.")
        break  # 退出for循环
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.