Вы должны обязательно проверить django-q! Это не требует дополнительной настройки и, возможно, все, что необходимо для решения любых производственных проблем в коммерческих проектах.
Он активно развивается и очень хорошо интегрируется с django, django ORM, mongo, redis. Вот моя конфигурация:
# django-q
# -------------------------------------------------------------------------
# See: http://django-q.readthedocs.io/en/latest/configure.html
Q_CLUSTER = {
# Match recommended settings from docs.
'name': 'DjangoORM',
'workers': 4,
'queue_limit': 50,
'bulk': 10,
'orm': 'default',
# Custom Settings
# ---------------
# Limit the amount of successful tasks saved to Django.
'save_limit': 10000,
# See https://github.com/Koed00/django-q/issues/110.
'catch_up': False,
# Number of seconds a worker can spend on a task before it's terminated.
'timeout': 60 * 5,
# Number of seconds a broker will wait for a cluster to finish a task before presenting it again. This needs to be
# longer than `timeout`, otherwise the same task will be processed multiple times.
'retry': 60 * 6,
# Whether to force all async() calls to be run with sync=True (making them synchronous).
'sync': False,
# Redirect worker exceptions directly to Sentry error reporter.
'error_reporter': {
'sentry': RAVEN_CONFIG,
},
}
Я думаю, может быть, это то, что вам нужно; возможность добавлять новые элементы в ваш список, даже когда вы его повторяете. Код уродливый, но вроде работает.
import scala.collection.mutable.Queue
class Circular[A](list: Seq[A]) extends Iterator[A]{
val elements = new Queue[A] ++= list
var pos = 0
def next = {
if (pos == elements.length)
pos = 0
val value = elements(pos)
pos = pos + 1
value
}
def hasNext = !elements.isEmpty
def add(a: A): Unit = { elements += a }
override def toString = elements.toString
}
Вы можете использовать это так:
scala> var circ = new Circular(List(1,2))
res26: Circular[Int] = Queue(1,2)
scala> circ.next
res27: Int = 1
scala> circ.next
res28: Int = 2
scala> circ.next
res29: Int = 1
scala> circ.add(5)
scala> circ.next
res30: Int = 2
scala> circ.next
res31: Int = 5
scala> circ
res32: Circular[Int] = Queue(1,2,5)
Такого рода вещи действительно заслуживают того, чтобы быть в стандартной потоковой библиотеке, но, похоже, это не так. Ответ dbryne с потоком работает хорошо, или, если вы предпочитаете его в форме для понимания
val listToRepeat:List[Foo]
val forever:Stream[Foo] = for(x<-Stream.continually(1); y<-listToRepeat) yield y
Первый генератор потока поддерживает все навсегда, даже если вы игнорируете значение. Второй генератор неявно сплющивается в нужный бесконечный поток.
Один из вариантов - использовать класс Stream
для создания ленивой, круговой, бесконечной последовательности:
scala> val values = List(1, 2, 3)
values: List[Int] = List(1, 2, 3)
scala> Stream.continually(values.toStream).flatten.take(9).toList
res2: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2, 3)
или вот так:
val values = List(1, 2, 3)
def circularStream(values: List[Int],
remaining: List[Int] = List()): Stream[Int] = {
if (remaining.isEmpty)
circularStream(values,values)
else
Stream.cons(remaining.head, circularStream(values, remaining.drop(1)))
}
circularStream(values).take(9).toList //Same result as example #1
def forever:Stream[Int] = Stream(1,2,3) append forever