Make page visit operation atomic
authorLanius Trolling <lanius@laniustrolling.dev>
Sun, 10 Mar 2024 14:59:05 +0000 (10:59 -0400)
committerLanius Trolling <lanius@laniustrolling.dev>
Sun, 10 Mar 2024 14:59:05 +0000 (10:59 -0400)
src/jvmMain/kotlin/info/mechyrdia/data/data.kt
src/jvmMain/kotlin/info/mechyrdia/data/visits.kt

index 7aefc798f0d67b8e70bdf09e0e2a7804d5d8650e..d9c7b24a6a2830c138436eb90609fbef353e4bca 100644 (file)
@@ -167,6 +167,10 @@ class DocumentTable<T : DataDocument<T>>(private val kClass: KClass<T>) {
                collection().updateMany(where, set)
        }
        
+       suspend fun change(where: Bson, set: Bson) {
+               collection().updateOne(where, set, UpdateOptions().upsert(true))
+       }
+       
        suspend fun remove(where: Bson) {
                collection().deleteMany(where)
        }
index 7c1de939222e2a77a0a5fcbbe7e4ed2424a9b6fd..335b7b81456dde53850213ed2de3de7ccac856e8 100644 (file)
@@ -3,6 +3,7 @@ package info.mechyrdia.data
 import com.mongodb.client.model.Accumulators
 import com.mongodb.client.model.Aggregates
 import com.mongodb.client.model.Filters
+import com.mongodb.client.model.Updates
 import info.mechyrdia.lore.dateTime
 import io.ktor.server.application.*
 import io.ktor.server.plugins.*
@@ -46,27 +47,17 @@ data class PageVisitData(
                }
                
                suspend fun visit(path: String, visitor: String) {
-                       val data = Table.locate(
+                       Table.change(
                                Filters.and(
                                        Filters.eq(PageVisitData::path.serialName, path),
                                        Filters.eq(PageVisitData::visitor.serialName, visitor)
+                               ),
+                               Updates.combine(
+                                       Updates.inc(PageVisitData::visits.serialName, 1),
+                                       Updates.set(PageVisitData::lastVisit.serialName, Instant.now()),
+                                       Updates.setOnInsert(MONGODB_ID_KEY, Id<PageVisitData>())
                                )
                        )
-                       if (data == null)
-                               Table.put(
-                                       PageVisitData(
-                                               path = path,
-                                               visitor = visitor,
-                                               visits = 1L,
-                                       )
-                               )
-                       else
-                               Table.put(
-                                       data.copy(
-                                               visits = data.visits + 1,
-                                               lastVisit = Instant.now()
-                                       )
-                               )
                }
                
                suspend fun totalVisits(path: String): PageVisitTotals {