Я нашел несколько статей и исходный код будущего и обещаний Scala:
но я все еще не очень понимаю, как на самом деле связывание обещанияработает.Прежде всего, стресс-тест истощения памяти ссылается на большие массивы в обратных вызовах.Это должно привести к тому, что большие массивы останутся в памяти, пока не будут выполнены обратные вызовы?
Я попытался написать сценарий стресс-теста в псевдокоде.
Пример, показывающий вызов сi = 3:
x4 = call3
call3 = {
val array3 = new BigArray
val f3 = Future { 3 }
x3 = f3.flatMap( 3 => array3; call2 )
return x3
}
call2 = {
val array2 = new BigArray
val f2 = Future { 2 }
x2 = f2.flatMap( 2 => array2; call1 )
return x2
}
call1 = {
val array1 = new BigArray
val f1 = Future { 1 }
x1 = f1.flatMap( 1 => array1; call0 )
return x1
}
call0 = {
val array0 = new BigArray
val f0 = Future { 0 }
x0 = f0.flatMap( 0 => Future.succesful() )
return x0
}
Обычно x0, x1, x2 и x3 запускаются при завершении f0, f1, f2 и f3 и затем вызывают их функции, например:
1 => array1; call0
так что это вызовет x1.completeWith(call0)
, что в основном равно x1.completeWith(x0)
.
Это приведет к следующей цепочке:
x4.completeWith(x3)
x3.completeWith(x2)
x2.completeWith(x1)
x1.completeWith(x0)
x0.completeWith(Future.successful())
Насколько я понимаю, так как все вызовы приводят ктот же результат, они могут быть связаны как:
x4.completeWith(Future.successful())
Пока все обратные вызовы из x0, x1, x2 и x3 перемещаются в x4.Все фьючерсы / обещания становятся идентичными?
Теперь, как связывание обещаний ведет себя точно в Scala 2.13.xx?Является ли x4 корнем, который ожидает завершения других фьючерсов?Другие фьючерсы / обещания теперь конвертируются в Link [T]?Кажется, что метод linkRootOf
в реализации Scala 2.13.xx создает новую ссылку на цель и сохраняет ее в состоянии будущее / обещание.Он заменяет свои обратные вызовы им.Обратные вызовы перемещаются в корневую цель будущего / обещания, которая будет выполнена, когда корневое будущее / обещание завершено?Это происходит, когда f0 завершено.
Даже если есть цепочка ссылок на корневое будущее / обещание, я не понимаю, почему он больше не течет?
Ссылки избольшие массивы доступны, когда f0, f1, f2 и f3 завершены с тех пор, как выполняются обратные вызовы.Но разве это не время, когда ссылки создаются, поэтому ссылки уже ушли?completeWith
не должно быть никаких блокировок, чтобы массивы могли быть освобождены даже без создания ссылки?