sh1marin on Nostr: 就算用了 teloxide 两年,我还是想劝大部分的人放过自己,别用 ...
就算用了 teloxide 两年,我还是想劝大部分的人放过自己,别用 teloxide 写 bot。他们的 dptree 玩 abstraction 玩的太抽象了,出现任何 type system 的问题,真正错误全被隐藏在他们的 abstraction 后面,于是写 tg bot 变成了一个实验,一点点实验什么类型能满足他那个莫名其妙的 trait bound。
今天又撞了一个很傻逼的坑,报错不满足 Injectable<Input, Output, FnArgs> ,然后自己慢慢推断类型,基本上就是要求 input output 都是 Send + Sync 的,而我所有的 async 函数单测都正常工作的。自己在函数 signature 加了 Send Sync ‘static constraint 也完全没有问题,折腾了半个多小时也想不明白究竟是哪里让 teloxide 不开心了。
还好后来想到了能用 tokio::spawn 包一下,才终于发现根本原因:Rc<UnsafeCell<ReseedingRng<rand_chacha::chacha::ChaCha12Core, OsRng>>> cannot be sent between threads safely。在 async 函数里调用了 rand::thread_rng,又没有在 await 之前 drop 掉 ThreadRng,导致函数本身不 Send 了。而这个问题却会被 dptree 的顶层 abstraction trait bound 给藏起来。
今天又撞了一个很傻逼的坑,报错不满足 Injectable<Input, Output, FnArgs> ,然后自己慢慢推断类型,基本上就是要求 input output 都是 Send + Sync 的,而我所有的 async 函数单测都正常工作的。自己在函数 signature 加了 Send Sync ‘static constraint 也完全没有问题,折腾了半个多小时也想不明白究竟是哪里让 teloxide 不开心了。
还好后来想到了能用 tokio::spawn 包一下,才终于发现根本原因:Rc<UnsafeCell<ReseedingRng<rand_chacha::chacha::ChaCha12Core, OsRng>>> cannot be sent between threads safely。在 async 函数里调用了 rand::thread_rng,又没有在 await 之前 drop 掉 ThreadRng,导致函数本身不 Send 了。而这个问题却会被 dptree 的顶层 abstraction trait bound 给藏起来。