简体   繁体   中英

Why my code work well in windows, but not in ubuntu

This code works well in windows, but when I move it to my vps (ubuntu16.04, python3.6), there is some problem.

import json
import time
import threading
import websocket
import requests
from datetime import datetime, timedelta, timezone

def run_in_thread(sec):
    def _wrapper(func):
        def __wrapper(self, *args, **kwargs):
            timer = threading.Timer(sec, func, [self, *args])
            timer.start()
            self._ws.on_open = self.on_open
            self._ws.run_forever()
            return self._result
        return __wrapper
    return _wrapper

class CybexHistoryAPI(object):
    def __init__(self, ws_endp):
        self._endpoint = ws_endp
        self.reset()

    def reset(self):
        self._ws = websocket.WebSocketApp(self._endpoint,
            on_message = self.on_message,
            on_error = self.on_error,
            on_close = self.on_close)
        self._login_api_id = -1
        self._history_api_id = -1
        self._api_is_ready = False
        self._call_id = 1

    def _send_msg(self, params):
        call = {"id": self._call_id, "method": "call",
                "params": params}
        self._ws.send(json.dumps(call))
        self._call_id += 1

    def on_open(self, ws):
        self._send_msg([1, "login", ["",""]])
        self._call_id = 1

    def on_error(self, ws, error):
        print('Remote node send an error [{}]'.format(error))

    def on_close(self, ws):
        print('Remote node closed our connection')

    def on_message(self, ws, msg):
        print(msg)
        if self._login_api_id < 0:
            result = json.loads(msg)
            self._login_api_id = result['id']
            self._send_msg([self._login_api_id, "history", []])
        elif self._history_api_id < 0:
            result = json.loads(msg)
            self._history_api_id = result['result']
            self._api_is_ready = True
        else:
            self._result = json.loads(msg)['result']
            self._ws.close()
            self.reset()

    @run_in_thread(0.01)
    def get_account_history(self, account_id, stop, limit, start):
        while not self._api_is_ready:
            time.sleep(0.01)
        self._send_msg([self._history_api_id, "get_account_history",
            [account_id, stop, limit, start]])

    @run_in_thread(0.01)
    def get_market_history(self, base_id, quote_id, ts, start, end):
        while not self._api_is_ready:
            time.sleep(0.01)
        self._send_msg([self._history_api_id, "get_market_history",
            [base_id, quote_id, ts, start, end]])

    @run_in_thread(0.01)
    def get_fill_order_history(self, base_id, quote_id, limit):
        while not self._api_is_ready:
            time.sleep(0.01)
        self._send_msg([self._history_api_id, "get_fill_order_history",
            [base_id, quote_id, limit]])

def scan_account(acc_id, max_len = 100):
    api = CybexHistoryAPI('wss://shanghai.51nebula.com')
    start = 0
    tot_len = 0
    while tot_len < max_len:
        print('start at 1.11.{}'.format(start))
        ret = api.get_account_history(acc_id, '1.11.1', 100, '1.11.' + str(start))
        if len(ret) == 0 or int(ret[0]['id'].split('.')[-1]) == start:
            break
        tot_len += len(ret)
        print('got {}'.format(len(ret)))
        print('end at {}'.format(ret[-1]['id']))
        #print(json.dumps(ret, indent=2))
        start = int(ret[-1]['id'].split('.')[-1]) - 1

    print(tot_len)
    return

def run_test():
    scan_account('1.2.38696')

if __name__ == '__main__':
    run_test()

I get the following error:

Traceback (most recent call last):
File "ListenTransferRecord.py", line 197, in <module>
    run_test()
File "ListenTransferRecord.py", line 186, in run_test
    respone = scan_account(accountID,10)
File "ListenTransferRecord.py", line 147, in scan_account
    ret = api.get_account_history(acc_id, '1.11.1', 100, '1.11.' + str(start))
File "ListenTransferRecord.py", line 71, in __wrapper
    return self._result
AttributeError: 'CybexHistoryAPI' object has no attribute '_result'

I don't understand why it can work well in windows but not in ubuntu.

And I've tried run some simple code in my VPS(ubuntu) to test if the python environment is ok.

I've tried reinstalling all the modules of this code import. But it is still not working.

The error you get just happens to trigger a bug that was already there - self._result is only set on a specific condition (in the else branch in the on_message method) but you unconditionnally access it in your decorator. For some reason (which we can't tell without much more details - actually chances are no one can tell without testing the code in your exact environment) you never (so far) stumbled on this case when running the code on Window, but the bug itself isn't dependent of the environment itself. The fix here is quite simple: just make sure the _result attribute is always set (eventually to some sentinel value like None :

def on_message(self, ws, msg):
    print(msg)

    self._result = None # default value

    if self._login_api_id < 0:
        result = json.loads(msg)
        self._login_api_id = result['id']
        self._send_msg([self._login_api_id, "history", []])
    elif self._history_api_id < 0:
        result = json.loads(msg)
        self._history_api_id = result['result']
        self._api_is_ready = True
    else:
        self._result = json.loads(msg)['result']
        self._ws.close()
        self.reset()

As to why you have different behaviour on different environment, this can come from so many reasons that one can't be sure to list them all... it might come from network latency and synchronisation issues between your threads, OS specific implementation details, phase of the moon, whatever, and as I said those are mostly the kind of issues that can be just impossible to troubleshout without direct access to both your environments.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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