Skip to content

Commit

Permalink
refactor(backend): optimize agenda calls.
Browse files Browse the repository at this point in the history
Closes #118
  • Loading branch information
GerardPaligot committed Dec 7, 2024
1 parent 9431af0 commit a002dd3
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,17 @@ import com.paligot.confily.backend.internals.helpers.database.getDocument
import com.paligot.confily.backend.internals.helpers.database.getDocuments
import com.paligot.confily.backend.internals.helpers.database.update
import com.paligot.confily.backend.internals.helpers.database.upsert
import com.paligot.confily.backend.internals.helpers.storage.MimeType
import com.paligot.confily.backend.internals.helpers.storage.Storage
import com.paligot.confily.backend.internals.helpers.storage.Upload
import com.paligot.confily.models.AgendaV4
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json

class EventDao(
private val projectName: String,
private val firestore: Firestore
private val firestore: Firestore,
private val storage: Storage
) {
fun list(): List<EventDb> = firestore
.collection(projectName)
Expand Down Expand Up @@ -73,4 +80,15 @@ class EventDao(
.collection(projectName)
.update(event.slugId, event.copy(agendaUpdatedAt = System.currentTimeMillis()))
}

suspend fun getAgendaFile(eventId: String, updateAt: Long): AgendaV4? =
storage.download("$eventId/agenda/$updateAt.json")
?.let { Json.decodeFromString(it.decodeToString()) }

suspend fun uploadAgendaFile(eventId: String, updateAt: Long, agendaV4: AgendaV4): Upload =
storage.upload(
filename = "$eventId/agenda/$updateAt.json",
content = Json.encodeToString(agendaV4).toByteArray(),
mimeType = MimeType.JSON
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.paligot.confily.backend.events
import com.paligot.confily.backend.categories.CategoryModule.categoryDao
import com.paligot.confily.backend.formats.FormatModule.formatDao
import com.paligot.confily.backend.internals.GoogleServicesModule.cloudFirestore
import com.paligot.confily.backend.internals.InternalModule
import com.paligot.confily.backend.internals.SystemEnv.projectName
import com.paligot.confily.backend.partners.PartnerModule.partnerDao
import com.paligot.confily.backend.qanda.QAndAModule.qAndADao
Expand All @@ -12,7 +13,9 @@ import com.paligot.confily.backend.speakers.SpeakerModule.speakerDao
import com.paligot.confily.backend.third.parties.geocode.GeocodeModule.geocodeApi

object EventModule {
val eventDao = lazy { EventDao(projectName, cloudFirestore.value) }
val eventDao = lazy {
EventDao(projectName, cloudFirestore.value, InternalModule.storage.value)
}
val eventRepository = lazy {
EventRepository(
geocodeApi.value,
Expand Down Expand Up @@ -52,6 +55,7 @@ object EventModule {
}
val eventRepositoryV4 = lazy {
EventRepositoryV4(
eventDao.value,
speakerDao.value,
sessionDao.value,
categoryDao.value,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,27 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope

@Suppress("LongParameterList")
class EventRepositoryV4(
private val eventDao: EventDao,
private val speakerDao: SpeakerDao,
private val sessionDao: SessionDao,
private val categoryDao: CategoryDao,
private val formatDao: FormatDao,
private val scheduleItemDao: ScheduleItemDao,
private val dispatcher: CoroutineDispatcher = Dispatchers.IO
) {
suspend fun agenda(eventDb: EventDb) = coroutineScope {
suspend fun agenda(eventDb: EventDb): AgendaV4 =
eventDao.getAgendaFile(eventDb.slugId, eventDb.agendaUpdatedAt) ?: buildAgenda(eventDb)

suspend fun generateAgenda(eventId: String, apiKey: String) = coroutineScope {
val eventDb = eventDao.getVerified(eventId, apiKey)
val agenda = buildAgenda(eventDb)
eventDao.uploadAgendaFile(eventId, eventDb.agendaUpdatedAt, agenda)
return@coroutineScope agenda
}

private suspend fun buildAgenda(eventDb: EventDb) = coroutineScope {
val schedules = async(context = dispatcher) {
scheduleItemDao.getAll(eventDb.slugId).map { it.convertToModelV4() }
}.await()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ fun Routing.registerEventRoutes() {
}
}
}
put("/events/{eventId}/agenda") {
val eventId = call.parameters["eventId"]!!
val apiKey = call.request.headers["api_key"]!!
call.respond(HttpStatusCode.OK, repositoryV4.generateAgenda(eventId, apiKey))
}
get("/events/{eventId}/openfeedback") {
val eventId = call.parameters["eventId"]!!
call.respond(HttpStatusCode.OK, repositoryV2.openFeedback(eventId))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.paligot.confily.backend.internals.helpers.storage
import com.google.cloud.storage.Acl
import com.google.cloud.storage.BlobId
import com.google.cloud.storage.BlobInfo
import com.google.cloud.storage.StorageException
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
Expand All @@ -13,6 +14,16 @@ class BucketStorage(
private val bucketName: String,
private val dispatcher: CoroutineDispatcher = Dispatchers.Default
) : Storage {
@Suppress("SwallowedException")
override suspend fun download(filename: String): ByteArray? = withContext(dispatcher) {
val blobId = BlobId.of(bucketName, filename)
return@withContext try {
storage.readAllBytes(blobId)
} catch (ex: StorageException) {
null
}
}

override suspend fun upload(filename: String, content: ByteArray, mimeType: MimeType): Upload =
withContext(dispatcher) {
val blobId = BlobId.of(bucketName, filename)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ class LocalStorage(
private val location: String = "/tmp",
private val dispatcher: CoroutineDispatcher = Dispatchers.Default
) : Storage {
override suspend fun download(filename: String): ByteArray? = withContext(dispatcher) {
File("$location/$directory/$filename").readBytes()
}

override suspend fun upload(
filename: String,
content: ByteArray,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.paligot.confily.backend.internals.helpers.storage
import com.google.cloud.storage.Storage as CloudStorage

interface Storage {
suspend fun download(filename: String): ByteArray?
suspend fun upload(filename: String, content: ByteArray, mimeType: MimeType): Upload

object Factory {
Expand All @@ -22,6 +23,7 @@ enum class MimeType(val value: String) {
GIF("image/gif"),
SVG("image/svg+xml"),
WEBP("image/webp"),
JSON("application/json"),
OCTET_STREAM("application/octet-stream")
}

Expand Down

0 comments on commit a002dd3

Please sign in to comment.