简体   繁体   English

带插座连接的断管

[英]Broken Pipe with socket connection

I am using a socket connection to download data through a third party API. 我正在使用套接字连接通过第三方API下载数据。 It works fine for a while but every now and then my script will crash giving the following error: BrokenPipeError: [Errno 32] Broken pipe 它可以正常工作一段时间,但BrokenPipeError: [Errno 32] Broken pipe我的脚本会崩溃,并出现以下错误: BrokenPipeError: [Errno 32] Broken pipe

After some research it seems the suggestion ( link here ) is to do the following: 经过研究后,似乎建议( 链接在此处 )执行以下操作:

from signal import signal, SIGPIPE, SIG_DFL

signal(SIGPIPE,SIG_DFL)

However im firstly not sure what this actually does (im still confused after reading the python manual on signal). 但是我首先不确定这实际上是做什么的(我在阅读有关信号的python手册后仍然感到困惑)。 And I also don't know where to put the code. 而且我也不知道将代码放在哪里。

If anyone is familiar with this error please could you advise if this is infact the correct solution and where the signal(SIGPIPE,SIG_DFL) would be placed. 如果有人熟悉此错误,请告知您这是否确实是正确的解决方案以及signal(SIGPIPE,SIG_DFL)放置位置。 Should there be a try/except block inside which this is placed, or is it simply placed at the start of the program? 应该在其中放置try / except块,还是只是将其放置在程序的开头? Im confused. 我糊涂了。

Here's some of the relevant code. 这是一些相关的代码。 I basically have a dataframe consisting of several thousand items. 我基本上有一个包含数千个项目的数据框。 I loop through each item passing it to the download method. 我遍历传递给下载方法的每个项目。 The download method downloads the data via the api and then writes it to a database. 下载方法通过api下载数据,然后将其写入数据库。 I then move to the next item to download. 然后,我移至下一个项目进行下载。

def recv_data(sock, recv_buffer=4096, delim='\n'):

    buffer = ''
    data = True
    while data:
        data = sock.recv(recv_buffer)
        buffer += str(data.decode('latin-1'))

        while buffer.find(delim) != -1:
            line, buffer = buffer.split('\n', 1)
            yield line

def update_existing_symbol_data(engine, sock, exchange, exchange_id, symbol, symbol_id, start_date):
    data = ''
    message = #request data message
    sock.sendall(message.encode())

    for line in recv_data(sock):
        if "!ENDMSG!" in line:
            break
        data += line[:-2] + '\n'

    df = pd.read_csv(io.StringIO(data))
    df.set_index('date', inplace=True)
    df.to_sql('daily', engine, if_exists='append')

def main():
    df = #dataframe all symbols that need to be downloaded
    for index, row in df.iterrows():
        update_existing_symbol_data(args)

SIGPIPE is a POSIX thing that gets sent when a socket write operation fails. SIGPIPE是POSIX,在套接字写操作失败时发送。 The default behavior is for the signal (this is an OS/socket thing, not a Python thing) to just kill your process. 默认行为是信号(这是OS / socket的事情,而不是Python的事情)只是杀死您的进程。 Python instead gives it to you as an exception so that it's possible to write more robust programs. 相反,Python将它作为例外提供给您,以便可以编写更强大的程序。 But if you don't need to handle that event, which it sounds like you don't considering your use case, you can safely ignore it. 但是,如果您不需要处理该事件(听起来好像您没有考虑用例),则可以放心地忽略它。 There's no logic you need to do when you receive the signal, so the solution from that blog post should be fine. 收到信号时,您无需执行任何逻辑,因此该博客文章中的解决方案应该很好。 No try/except needed. 无需尝试/需要。

If your use case changes at a later date and you do need to handle the SIGPIPE, then wrapping that in a try/except and handling it there would be the way to go. 如果您的用例在以后发生更改,并且您确实需要处理SIGPIPE,那么将其包装在try / except中并进行处理就可以了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM