Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: AttributeError("'_thread._local' object has no attribute 'function_result_status'" #109

Closed
anjia0532 opened this issue Mar 20, 2024 · 7 comments

Comments

@anjia0532
Copy link

requirements.txt

redis==5.0.3
funboost==42.9
sqlalchemy==2.0.28
pymysql==0.7.7
db_libs==0.9

4.31 funboost_current_task 上下文获取当前消息和任务状态

import random
import time

from funboost import boost, FunctionResultStatusPersistanceConfig,BoosterParams
from funboost.core.current_task import funboost_current_task

# @boost(BoosterParams(queue_name='queue_test_fct', qps=2,concurrent_num=5,))
@boost(BoosterParams(queue_name='queue_test_fct', qps=2, concurrent_num=5, function_timeout=600, ))
def f(a, b):
    fct = funboost_current_task() # 线程/协程隔离级别的上下文
    print(fct.function_result_status.task_id) # 获取消息的任务id
    print(fct.function_result_status.run_times) # 获取消息是第几次重试运行
    print(fct.full_msg) # 获取消息的完全体。出了a和b的值意外,还有发布时间 task_id等。
    print(fct.function_result_status.publish_time) # 获取消息的发布时间
    print(fct.function_result_status.get_status_dict()) # 获取任务的信息,可以转成字典看。

    time.sleep(20)
    if random.random() > 0.5:
        raise Exception(f'{a} {b} 模拟出错啦')
    print(a+b)

    return a + b


if __name__ == '__main__':
    # f(5, 6)  # 可以直接调用

    for i in range(0, 200):
        f.push(i, b=i * 2)

    f.consume()

加上 function_timeout 会报错 AttributeError: '_thread._local' object has no attribute 'function_result_status' 去掉就正常

@ydf0509
Copy link
Owner

ydf0509 commented Mar 20, 2024

这个是我意料之中的, 超时杀死和支持远程杀死 这两个功能都是吧函数包装在另外一个单独的线程里面去运行的,和funboost设置到上下文时候不是在同一个线程里面,所以获取不到的, 要兼容这两个功能代码还需要改造的,要去注超时装饰器和支持远程杀死装饰器里面去改代码了,需要把一个线程的上下文赋值到这个新的独立包装线程里面去,需要等待一段时间我再实现.

超时杀死和远程杀死这两个功能,已经提示了不要轻易使用的, 因为要支持杀死,就要把它放到一个单独的线程里面运行,杀死函数其实就是使用c语言的ctypes 杀死这个函数运行所在的线程,如果杀死函数时候,用户函数获取了线程锁,但是还没释放,程序会永远死锁,

而且设置超时杀死,代码性能明显又会下降一截,因为每次运行消息都要新创建一个线程,非必要别使用.
你现在是必须要用超时杀死吗?

@ydf0509
Copy link
Owner

ydf0509 commented Mar 20, 2024

这个问题和上个回答你添加taskid一样, 所谓的上下文 必须是同一个线程/协程下才行,

@ydf0509
Copy link
Owner

ydf0509 commented Mar 20, 2024

funboost_current_task 是刚加的,现在不兼容设置函数超时杀死和远程杀死

@anjia0532
Copy link
Author

明白了,但是感觉可以在文档说明一下。因为直观的感受就是莫名的时好时坏(有的队列没加超时杀死,有的加了,或者开始没加好使,后来加了又报错了)

@anjia0532
Copy link
Author

这个是我意料之中的, 超时杀死和支持远程杀死 这两个功能都是吧函数包装在另外一个单独的线程里面去运行的,和funboost设置到上下文时候不是在同一个线程里面,所以获取不到的, 要兼容这两个功能代码还需要改造的,要去注超时装饰器和支持远程杀死装饰器里面去改代码了,需要把一个线程的上下文赋值到这个新的独立包装线程里面去,需要等待一段时间我再实现.

超时杀死和远程杀死这两个功能,已经提示了不要轻易使用的, 因为要支持杀死,就要把它放到一个单独的线程里面运行,杀死函数其实就是使用c语言的ctypes 杀死这个函数运行所在的线程,如果杀死函数时候,用户函数获取了线程锁,但是还没释放,程序会永远死锁,

而且设置超时杀死,代码性能明显又会下降一截,因为每次运行消息都要新创建一个线程,非必要别使用. 你现在是必须要用超时杀死吗?

倒也不是非得用,就是做个兜底,防止某些个别消息处理太慢,一直挂着

@ydf0509
Copy link
Owner

ydf0509 commented Mar 20, 2024

image
搞定了,吧消费线程的上下文传递到超时装饰器启动的线程里面来,因为设置超时杀死后,用户的函数实际是超时装饰器里面另外起了个线程里面运行的.

@anjia0532
Copy link
Author

更新新版试了下,已经可以了 。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants