У меня есть две корзины S3 под разными аккаунтами. Я хочу переместить файлы из Bucket A в Bucket B, и я хочу сделать это как можно быстрее. Для этого я решил использовать Scala, асинхронные запросы и параллельную обработку для максимально быстрого перемещения файлов.
Для этого мне нужно вызвать команду listObjects (которая возвращает свое будущее, а затем для каждого объекта, возвращаемого этой командой, мне нужно последовательно запустить getObject, а затем putObject. Следовательно, затем listObjects должен порождает несколько фьючерсов getObject, и когда эти фьючерсы разрешаются, за ними следует фьючерс на putObject.
Я пытался сделать это примерно так:
def moveData(listObjects: Future[ListObjectV2Response]) = {
listObjects.isCompleted {
case Success(objListResp) =>
val getAndPut = objListResp.objects()
.map(obj => getObject(obj.key))
.map(obj => putObject(obj.key))
moveData(ListObjects(objlistResp.continuationToken())
case Failure(error) => error.printStackTrace()
}
Я попробовал какой-то подход в этом аромате около 6 разных способов. Меня постоянно сбивают с толку следующие явления:
.isCompleted
имеет тип ответа Unit, и я не могу получить его с помощью рекурсивной функции.
- Мне часто нужно передавать различные значения, например, listObjects отвечает на запросы PutObject. Это приводит к передаче 3+ статических значений по цепочке
.map
в виде фьючерсов.
- listObjects - это одно будущее, но вызов
.contents
возвращает итерацию, которую нужно преобразовать во множество различных вариантов будущего. Это в сочетании с (2) приводит к некоторым по-настоящему хитрым случаям использования map
и flatMap
, когда scala хочет, чтобы карта / плоская карта была чем-то вроде Iterator[S3Object] => Future[NotInferred]
, когда фактический тип ответа равен Iterator[S3Object] => Iterator((Future[GetObject], Future[String]))
Как мне подойти к этой проблеме? Есть ли способ лучше?
EDIT:
Есть тысячи файлов, многие из них в нескольких ГБ. Всего копируемых данных исчисляется десятками терабайт. У меня крайне ограниченный доступ к корзине с исходным кодом и к учетной записи, в которой она находится. У меня никогда не будет возможности делать что-либо кроме операций Get и List.