Skip to content

Commit

Permalink
add creatimeTimestamp to entities (kt)
Browse files Browse the repository at this point in the history
  • Loading branch information
mariakleiner committed Mar 3, 2020
1 parent 5c6310d commit 0380fe3
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 14 deletions.
6 changes: 5 additions & 1 deletion java/arcs/android/crdt/ParcelableRawEntity.kt
Expand Up @@ -39,6 +39,7 @@ data class ParcelableRawEntity(
parcel.writeTypedObject(ParcelableReferencable(it), flags)
}
}
parcel.writeLong(actual.creationTimestamp)
parcel.writeLong(actual.expirationTimestamp)
}

Expand Down Expand Up @@ -67,10 +68,13 @@ data class ParcelableRawEntity(
collections[key] = set
}

@Suppress("GoodTime") // use Instant
val creationTimestamp = requireNotNull(parcel.readLong())

@Suppress("GoodTime") // use Instant
val expirationTimestamp = requireNotNull(parcel.readLong())

val rawEntity = RawEntity(id, singletons, collections, expirationTimestamp)
val rawEntity = RawEntity(id, singletons, collections, creationTimestamp, expirationTimestamp)
return ParcelableRawEntity(rawEntity)
}

Expand Down
5 changes: 5 additions & 0 deletions java/arcs/core/common/Referencable.kt
Expand Up @@ -19,6 +19,11 @@ interface Referencable {
/** Unique identifier of the Referencable object. */
val id: ReferenceId

/** Creation timestamp (in millis) on the Referencable object. */
var creationTimestamp: Long
get() = TODO("not implemented")
set(@Suppress("UNUSED_PARAMETER") value) = TODO("not implemented")

/** Expiration timestamp (in millis) on the Referencable object. */
var expirationTimestamp: Long
get() = TODO("not implemented")
Expand Down
28 changes: 23 additions & 5 deletions java/arcs/core/data/RawEntity.kt
Expand Up @@ -29,21 +29,34 @@ data class RawEntity(
override fun unwrap(): Referencable {
val entity = RawEntity(
id = id,
creationTimestamp = creationTimestamp,
expirationTimestamp = expirationTimestamp,
singletons = singletons.mapValues { it.value?.unwrap() },
collections = collections.mapValues {
it.value.map { item -> item.unwrap() }.toSet()
}
)
entity.creationTimestamp = creationTimestamp
entity.expirationTimestamp = expirationTimestamp
return entity
}

/** Entity creation time (in millis). */
@Suppress("GoodTime") // use Instant
override var creationTimestamp: Long = UNINITIALIZED_TIMESTAMP
set(value) {
require(this.creationTimestamp == UNINITIALIZED_TIMESTAMP) {
"cannot override creationTimestamp $value"
}
@Suppress("GoodTime") // use Instant
field = value
}

/** Entity expiration time (in millis). */
@Suppress("GoodTime") // use Instant
override var expirationTimestamp: Long = NO_EXPIRATION
override var expirationTimestamp: Long = UNINITIALIZED_TIMESTAMP
set(value) {
require(this.expirationTimestamp == NO_EXPIRATION) {
require(this.expirationTimestamp == UNINITIALIZED_TIMESTAMP) {
"cannot override expirationTimestamp $value"
}
@Suppress("GoodTime") // use Instant
Expand All @@ -62,7 +75,8 @@ data class RawEntity(
id: ReferenceId = NO_REFERENCE_ID,
singletonFields: Set<FieldName> = emptySet(),
collectionFields: Set<FieldName> = emptySet(),
expirationTimestamp: Long = NO_EXPIRATION
creationTimestamp: Long = UNINITIALIZED_TIMESTAMP,
expirationTimestamp: Long = UNINITIALIZED_TIMESTAMP
) : this(
id,
singletonFields.associateWith { null },
Expand All @@ -73,17 +87,21 @@ data class RawEntity(

companion object {
const val NO_REFERENCE_ID = "NO REFERENCE ID"
const val NO_EXPIRATION: Long = -1
const val UNINITIALIZED_TIMESTAMP: Long = -1
}
}

fun RawEntity(
id: String,
singletons: Map<FieldName, Referencable?>,
collections: Map<FieldName, Set<Referencable>>,
creationTimestamp: Long,
expirationTimestamp: Long
) = RawEntity(
id,
singletons,
collections
).also { it.expirationTimestamp = expirationTimestamp }
).also {
it.creationTimestamp = creationTimestamp
it.expirationTimestamp = expirationTimestamp
}
2 changes: 1 addition & 1 deletion java/arcs/core/data/Ttl.kt
Expand Up @@ -34,7 +34,7 @@ sealed class Ttl(count: Int, val isInfinite: Boolean = false) {
override fun hashCode(): Int = minutes.hashCode()

fun calculateExpiration(time: Time): Long =
if (isInfinite) RawEntity.NO_EXPIRATION
if (isInfinite) RawEntity.UNINITIALIZED_TIMESTAMP
else requireNotNull(time).currentTimeMillis + (minutes * 60 * 1000)

data class Minutes(val count: Int) : Ttl(count)
Expand Down
2 changes: 2 additions & 0 deletions java/arcs/core/storage/handle/CollectionImpl.kt
Expand Up @@ -88,6 +88,8 @@ class CollectionImpl<T : Referencable>(
*/
suspend fun store(entity: T): Boolean {
log.debug { "Storing: $entity" }
@Suppress("GoodTime") // use Instant
entity.creationTimestamp = requireNotNull(time).currentTimeMillis;
if (!Ttl.Infinite.equals(ttl)) {
@Suppress("GoodTime") // use Instant
entity.expirationTimestamp = ttl.calculateExpiration(time)
Expand Down
2 changes: 2 additions & 0 deletions java/arcs/core/storage/handle/SingletonImpl.kt
Expand Up @@ -64,6 +64,8 @@ class SingletonImpl<T : Referencable>(
* did not apply fully. Fetch the latest value and retry.
* */
suspend fun store(entity: T): Boolean {
@Suppress("GoodTime") // use Instant
entity.creationTimestamp = requireNotNull(time).currentTimeMillis;
if (!Ttl.Infinite.equals(ttl)) {
@Suppress("GoodTime") // use Instant
entity.expirationTimestamp = ttl.calculateExpiration(time)
Expand Down
9 changes: 9 additions & 0 deletions java/arcs/sdk/android/dev/api/CollectionProxy.java
Expand Up @@ -286,6 +286,15 @@ public Referencable unwrap() {
return this;
}

@Override
public long getCreationTimestamp() {
throw new AssertionError("ModelEntry::getCreationTimestamp not implemented");
}

@Override
public void setCreationTimestamp(long creationTimestamp) {
throw new AssertionError("ModelEntry::setCreationTimestamp not implemented");
}

@Override
public long getExpirationTimestamp() {
Expand Down
11 changes: 8 additions & 3 deletions javatests/arcs/core/storage/handle/CollectionIntegrationTest.kt
Expand Up @@ -170,20 +170,25 @@ class CollectionIntegrationTest {
fun addElementsWithTtls() = runBlockingTest {
val person = Person("John", 29, false)
collectionA.store(person.toRawEntity())
val creationTimestampA = collectionA.fetchAll().first().creationTimestamp
assertThat(creationTimestampA).isNotEqualTo(RawEntity.UNINITIALIZED_TIMESTAMP)
assertThat(collectionA.fetchAll().first().expirationTimestamp)
.isEqualTo(RawEntity.NO_EXPIRATION)
.isEqualTo(RawEntity.UNINITIALIZED_TIMESTAMP)

val collectionC = CollectionImpl("collectionC", storageProxy, null, null, Ttl.Days(2), TimeImpl())
storageProxy.registerHandle(collectionC)
assertThat(collectionC.store(person.toRawEntity())).isTrue()
val entityC = collectionC.fetchAll().first()
assertThat(entityC.expirationTimestamp).isGreaterThan(RawEntity.NO_EXPIRATION)
assertThat(entityC.creationTimestamp).isGreaterThan(creationTimestampA)
assertThat(entityC.expirationTimestamp).isGreaterThan(RawEntity.UNINITIALIZED_TIMESTAMP)

val collectionD = CollectionImpl("collectionD", storageProxy, null, null, Ttl.Minutes(1), TimeImpl())
storageProxy.registerHandle(collectionD)
assertThat(collectionD.store(person.toRawEntity())).isTrue()
val entityD = collectionD.fetchAll().first()
assertThat(entityD.expirationTimestamp).isGreaterThan(RawEntity.NO_EXPIRATION)
assertThat(entityD.creationTimestamp).isGreaterThan(creationTimestampA)
assertThat(entityD.creationTimestamp).isGreaterThan(entityC.creationTimestamp)
assertThat(entityD.expirationTimestamp).isGreaterThan(RawEntity.UNINITIALIZED_TIMESTAMP)
assertThat(entityC.expirationTimestamp).isGreaterThan(entityD.expirationTimestamp)
}

Expand Down
11 changes: 8 additions & 3 deletions javatests/arcs/core/storage/handle/SingletonIntegrationTest.kt
Expand Up @@ -138,20 +138,25 @@ class SingletonIntegrationTest {
fun addEntityWithTtl() = runBlockingTest {
val person = Person("Jane", 29, false)
assertThat(singletonA.store(person.toRawEntity())).isTrue()
val creationTimestampA = requireNotNull(singletonA.fetch()).creationTimestamp;
assertThat(creationTimestampA).isNotEqualTo(RawEntity.UNINITIALIZED_TIMESTAMP)
assertThat(requireNotNull(singletonA.fetch()).expirationTimestamp)
.isEqualTo(RawEntity.NO_EXPIRATION)
.isEqualTo(RawEntity.UNINITIALIZED_TIMESTAMP)

val singletonC = SingletonImpl("singletonC", storageProxy, null, Ttl.Days(2), TimeImpl())
storageProxy.registerHandle(singletonC)
assertThat(singletonC.store(person.toRawEntity())).isTrue()
val entityC = requireNotNull(singletonC.fetch())
assertThat(entityC.expirationTimestamp).isGreaterThan(RawEntity.NO_EXPIRATION)
assertThat(entityC.creationTimestamp).isGreaterThan(creationTimestampA)
assertThat(entityC.expirationTimestamp).isGreaterThan(RawEntity.UNINITIALIZED_TIMESTAMP)

val singletonD = SingletonImpl("singletonD", storageProxy, null, Ttl.Minutes(1), TimeImpl())
storageProxy.registerHandle(singletonD)
assertThat(singletonD.store(person.toRawEntity())).isTrue()
val entityD = requireNotNull(singletonD.fetch())
assertThat(entityD.expirationTimestamp).isGreaterThan(RawEntity.NO_EXPIRATION)
assertThat(entityD.creationTimestamp).isGreaterThan(creationTimestampA)
assertThat(entityD.creationTimestamp).isGreaterThan(entityC.creationTimestamp)
assertThat(entityD.expirationTimestamp).isGreaterThan(RawEntity.UNINITIALIZED_TIMESTAMP)
assertThat(entityC.expirationTimestamp).isGreaterThan(entityD.expirationTimestamp)
}

Expand Down
2 changes: 1 addition & 1 deletion src/runtime/manifest.ts
Expand Up @@ -829,7 +829,7 @@ ${e.message}
for (const item of items.syntheticHandles) {
const handle = recipe.newHandle();
handle.fate = 'join';

if (item.name) {
assert(!items.byName.has(item.name), `duplicate handle name: ${item.name}`);
handle.localName = item.name;
Expand Down

0 comments on commit 0380fe3

Please sign in to comment.