我有一个工具,是使用一个电报聊天机器人与用户互动。
电报限制了呼叫速率,所以我使用了一个定期刷新的队列系统。
// flush the message queue
let flushMessageQueue() =
if not messageQueue.IsEmpty then <- messageQueue is a ConcurrentQueue
// get all the messages
let messages =
messageQueue
|> Seq.unfold(fun q ->
match q.TryDequeue () with
| true, m -> Some (m, q)
| _ -> None)
// put all the messages in a single string
let messagesString = String.Join("\n", messages)
// send the data
client.SendTextMessageAsync(chatId, messagesString, ParseMode.Markdown)
|> Async.AwaitTask
|> Async.RunSynchronously
|> ignore
这是按固定间隔调用的,而写入是:
// broadcast message
let broadcastMessage message =
messageQueue.Enqueue(message)
printfn "%s" (message.Replace ("```", String.Empty))
但随着信息变得越来越复杂,两个问题同时出现:
-
一些行块被包装在``节之间
-
在某些行中也有一些``节
-
一些文本示例可能是:
```
this is a group of lines
with one, or many many lines
```
and sometimes there are things ```like this``` as well
还有。。。我发现电报也将消息大小限制为4kb
-
我可以使用open/close ``来维护一个状态,并从队列中拉出,根据状态将每一行包装成三个回勾,然后推入另一个队列,该队列将用于生成4kb块。
-
我可以不断地从重新格式化的队列中获取消息并聚合它们,直到达到4kb,或者在队列末尾循环。
在F#有什么优雅的方法可以做到这一点吗?
我记得看到过一个片段,其中使用了一个collection函数来聚合数据,直到达到一定的大小,但它看起来非常低效,因为它正在收集line1、line1+line2、line1+line2+line3。。。然后挑一个大小合适的。