当Kotlin通道满时执行一段代码

当Kotlin通道满时执行一段代码,kotlin,channel,kotlin-coroutines,Kotlin,Channel,Kotlin Coroutines,我想编写一个简单的批处理程序类。它有一个请求队列,等待该队列变满或等待一段时间,然后才与数据库对话 通过通道实现这个队列非常方便,这样我们的客户机将在队列满时挂起。但我如何才能知道频道是否已满 当然,我可以创建一个方法,将某些内容发送到通道,然后执行一些检查。下一步是将其封装在从Channel派生的类中。仍然非常脏(不清楚如何处理onSend/onReceive)。还有其他优雅的解决方案吗?可能是一些现成的东西?通道接口声明了一个isFull属性,可以查询该属性以确定它是否已达到容量 我看不出是

我想编写一个简单的批处理程序类。它有一个请求队列,等待该队列变满或等待一段时间,然后才与数据库对话

通过通道实现这个队列非常方便,这样我们的客户机将在队列满时挂起。但我如何才能知道频道是否已满


当然,我可以创建一个方法,将某些内容发送到通道,然后执行一些检查。下一步是将其封装在从Channel派生的类中。仍然非常脏(不清楚如何处理
onSend
/
onReceive
)。还有其他优雅的解决方案吗?可能是一些现成的东西?

通道接口声明了一个isFull属性,可以查询该属性以确定它是否已达到容量


我看不出是否有回调函数在达到容量时自动调用函数,但您可以定期检查isFull属性以查看它是否达到容量

通道接口声明一个isFull属性,可以查询该属性以确定其是否已达到容量


我看不出是否有回调函数在达到容量时自动调用函数,但您可以定期检查isFull属性以查看它是否达到容量

这不是现成的,但是可以使用actor轻松实现相应的批处理逻辑。您实际上不需要一个类来实现这一点(但如果愿意,可以将此代码封装在一个类中)。您可以将以下实现用作模板:

const val MAX_SIZE = 100 // max number of data items in batch
const val MAX_TIME = 1000 // max time (in ms) to wait

val batchActor = actor<Data> {
    val batch = mutableListOf<Data>()
    var deadline = 0L // deadline for sending this batch to DB
    while (true) {
        // when deadline is reached or size is exceeded, then force batch to DB
        val remainingTime = deadline - System.currentTimeMillis()
        if (batch.isNotEmpty() && remainingTime <= 0 || batch.size >= MAX_SIZE) {
            saveToDB(batch)
            batch.clear()
            continue
        }
        // wait until items is received or timeout reached
        select<Unit> {
            // when received -> add to batch
            channel.onReceive {
                batch.add(it)
                // init deadline on first item added to batch
                if (batch.size == 1) deadline = System.currentTimeMillis() + MAX_TIME
            }
            // when timeout is reached just finish select, note: no timeout when batch is empty
            if (batch.isNotEmpty()) onTimeout(remainingTime) {}
        }
    }
}
const val MAX_SIZE=100//批处理中的最大数据项数
const val MAX_TIME=1000//等待的最大时间(毫秒)
val batchActor=actor{
val batch=mutableListOf()
var deadline=0L//将此批发送到DB的截止日期
while(true){
//当达到截止日期或超出大小时,则强制批处理到DB
val remainingTime=截止日期-System.currentTimeMillis()
if(batch.isNotEmpty()&&remainingTime=MAX\u SIZE){
saveToDB(批处理)
批处理清除()
持续
}
//等待,直到收到项目或达到超时
挑选{
//接收时->添加到批次
频道接收{
批处理添加(it)
//添加到批次的第一个项目的初始截止日期
如果(batch.size==1)截止日期=System.currentTimeMillis()+最大时间
}
//当达到超时时,只需完成选择,注意:批次为空时无超时
if(batch.isNotEmpty())onTimeout(remainingTime){}
}
}
}

现在,只要在需要向数据库发送任何内容时执行
batchActor.send(data)
,actor内部的逻辑负责批处理并将生成的批保存到数据库。

这不是现成的,但是可以使用actor轻松实现相应的批处理逻辑。您实际上不需要一个类来实现这一点(但如果愿意,可以将此代码封装在一个类中)。您可以将以下实现用作模板:

const val MAX_SIZE = 100 // max number of data items in batch
const val MAX_TIME = 1000 // max time (in ms) to wait

val batchActor = actor<Data> {
    val batch = mutableListOf<Data>()
    var deadline = 0L // deadline for sending this batch to DB
    while (true) {
        // when deadline is reached or size is exceeded, then force batch to DB
        val remainingTime = deadline - System.currentTimeMillis()
        if (batch.isNotEmpty() && remainingTime <= 0 || batch.size >= MAX_SIZE) {
            saveToDB(batch)
            batch.clear()
            continue
        }
        // wait until items is received or timeout reached
        select<Unit> {
            // when received -> add to batch
            channel.onReceive {
                batch.add(it)
                // init deadline on first item added to batch
                if (batch.size == 1) deadline = System.currentTimeMillis() + MAX_TIME
            }
            // when timeout is reached just finish select, note: no timeout when batch is empty
            if (batch.isNotEmpty()) onTimeout(remainingTime) {}
        }
    }
}
const val MAX_SIZE=100//批处理中的最大数据项数
const val MAX_TIME=1000//等待的最大时间(毫秒)
val batchActor=actor{
val batch=mutableListOf()
var deadline=0L//将此批发送到DB的截止日期
while(true){
//当达到截止日期或超出大小时,则强制批处理到DB
val remainingTime=截止日期-System.currentTimeMillis()
if(batch.isNotEmpty()&&remainingTime=MAX\u SIZE){
saveToDB(批处理)
批处理清除()
持续
}
//等待,直到收到项目或达到超时
挑选{
//接收时->添加到批次
频道接收{
批处理添加(it)
//添加到批次的第一个项目的初始截止日期
如果(batch.size==1)截止日期=System.currentTimeMillis()+最大时间
}
//当达到超时时,只需完成选择,注意:批次为空时无超时
if(batch.isNotEmpty())onTimeout(remainingTime){}
}
}
}

现在,只要在需要向数据库发送任何内容时执行
batchActor.send(data)
,actor内部的逻辑就可以处理批处理并将生成的批保存到数据库中。

感谢您提供如此详细的答案!我一定要接受。虽然代码看起来很重要,但请您提供这样详细的答案!我一定要接受。虽然代码看起来很有必要