From 5dee18a7cdb39789a86fe802a61c08f88144bffa Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 29 Dec 2025 12:15:06 +0000 Subject: [PATCH 1/2] Initial plan From 73eb29268b5da7b8bfe7f7a76019884af23ebc2d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 29 Dec 2025 12:25:57 +0000 Subject: [PATCH 2/2] Fix logging effect sequencing in S3Writer Use flatTap and *> operators to properly sequence logging effects instead of discarding them. This ensures logging is actually performed. Co-authored-by: akreit <64101884+akreit@users.noreply.github.com> --- .../com/async2databricks/s3/S3Writer.scala | 61 ++++++++++--------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/src/main/scala/com/async2databricks/s3/S3Writer.scala b/src/main/scala/com/async2databricks/s3/S3Writer.scala index 20ef778..9752230 100644 --- a/src/main/scala/com/async2databricks/s3/S3Writer.scala +++ b/src/main/scala/com/async2databricks/s3/S3Writer.scala @@ -44,21 +44,16 @@ object S3Writer extends CatsLogger { .region(Region.of(config.region)) // Use custom endpoint for LocalStack - val client = - if ( - config.endpoint.nonEmpty && config.endpoint != "https://s3.amazonaws.com" - ) { - builder.endpointOverride(URI.create(config.endpoint)).build() - } else { - builder.build() - } - - // Log effectfully - log.info( - s"S3 client created for endpoint: ${config.endpoint}" - ) // Only for side-effect, not recommended in prod - client - } + if ( + config.endpoint.nonEmpty && config.endpoint != "https://s3.amazonaws.com" + ) { + builder.endpointOverride(URI.create(config.endpoint)).build() + } else { + builder.build() + } + }.flatTap(client => + log.info(s"S3 client created for endpoint: ${config.endpoint}") + ) }(client => Async[F].delay(client.close())) } @@ -69,23 +64,29 @@ object S3Writer extends CatsLogger { bucketName: String ): F[Unit] = { val log = logger[F] - Async[F].delay { - try { - s3Client.headBucket( - HeadBucketRequest.builder().bucket(bucketName).build() - ) - log.info( - s"Bucket $bucketName already exists" - ) // Only for side-effect, not recommended in prod - } catch { - case _: NoSuchBucketException => - log.info(s"Creating bucket $bucketName") - s3Client.createBucket( - CreateBucketRequest.builder().bucket(bucketName).build() + Async[F] + .delay { + try { + s3Client.headBucket( + HeadBucketRequest.builder().bucket(bucketName).build() ) - log.info(s"Bucket $bucketName created successfully") + Some(()) + } catch { + case _: NoSuchBucketException => None + } + } + .flatMap { + case Some(_) => + log.info(s"Bucket $bucketName already exists") + case None => + log.info(s"Creating bucket $bucketName") *> + Async[F].delay( + s3Client.createBucket( + CreateBucketRequest.builder().bucket(bucketName).build() + ) + ) *> + log.info(s"Bucket $bucketName created successfully") } - } } def apply[F[_]: Async](config: S3Config): Resource[F, S3Writer[F]] = {