Skip to content

Commit d032c75

Browse files
authored
add creatimeTimestamp to entities (kt) (#4823)
1 parent 30267fc commit d032c75

File tree

10 files changed

+70
-14
lines changed

10 files changed

+70
-14
lines changed

java/arcs/android/crdt/ParcelableRawEntity.kt

+11-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ data class ParcelableRawEntity(
3939
parcel.writeTypedObject(ParcelableReferencable(it), flags)
4040
}
4141
}
42+
parcel.writeLong(actual.creationTimestamp)
4243
parcel.writeLong(actual.expirationTimestamp)
4344
}
4445

@@ -67,10 +68,19 @@ data class ParcelableRawEntity(
6768
collections[key] = set
6869
}
6970

71+
@Suppress("GoodTime") // use Instant
72+
val creationTimestamp = requireNotNull(parcel.readLong())
73+
7074
@Suppress("GoodTime") // use Instant
7175
val expirationTimestamp = requireNotNull(parcel.readLong())
7276

73-
val rawEntity = RawEntity(id, singletons, collections, expirationTimestamp)
77+
val rawEntity = RawEntity(
78+
id,
79+
singletons,
80+
collections,
81+
creationTimestamp,
82+
expirationTimestamp
83+
)
7484
return ParcelableRawEntity(rawEntity)
7585
}
7686

java/arcs/core/common/Referencable.kt

+5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ interface Referencable {
1919
/** Unique identifier of the Referencable object. */
2020
val id: ReferenceId
2121

22+
/** Creation timestamp (in millis) on the Referencable object. */
23+
var creationTimestamp: Long
24+
get() = TODO("not implemented")
25+
set(@Suppress("UNUSED_PARAMETER") value) = TODO("not implemented")
26+
2227
/** Expiration timestamp (in millis) on the Referencable object. */
2328
var expirationTimestamp: Long
2429
get() = TODO("not implemented")

java/arcs/core/data/RawEntity.kt

+23-5
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,34 @@ data class RawEntity(
2929
override fun unwrap(): Referencable {
3030
val entity = RawEntity(
3131
id = id,
32+
creationTimestamp = creationTimestamp,
3233
expirationTimestamp = expirationTimestamp,
3334
singletons = singletons.mapValues { it.value?.unwrap() },
3435
collections = collections.mapValues {
3536
it.value.map { item -> item.unwrap() }.toSet()
3637
}
3738
)
39+
entity.creationTimestamp = creationTimestamp
3840
entity.expirationTimestamp = expirationTimestamp
3941
return entity
4042
}
4143

44+
/** Entity creation time (in millis). */
45+
@Suppress("GoodTime") // use Instant
46+
override var creationTimestamp: Long = UNINITIALIZED_TIMESTAMP
47+
set(value) {
48+
require(this.creationTimestamp == UNINITIALIZED_TIMESTAMP) {
49+
"cannot override creationTimestamp $value"
50+
}
51+
@Suppress("GoodTime") // use Instant
52+
field = value
53+
}
54+
4255
/** Entity expiration time (in millis). */
4356
@Suppress("GoodTime") // use Instant
44-
override var expirationTimestamp: Long = NO_EXPIRATION
57+
override var expirationTimestamp: Long = UNINITIALIZED_TIMESTAMP
4558
set(value) {
46-
require(this.expirationTimestamp == NO_EXPIRATION) {
59+
require(this.expirationTimestamp == UNINITIALIZED_TIMESTAMP) {
4760
"cannot override expirationTimestamp $value"
4861
}
4962
@Suppress("GoodTime") // use Instant
@@ -62,7 +75,8 @@ data class RawEntity(
6275
id: ReferenceId = NO_REFERENCE_ID,
6376
singletonFields: Set<FieldName> = emptySet(),
6477
collectionFields: Set<FieldName> = emptySet(),
65-
expirationTimestamp: Long = NO_EXPIRATION
78+
creationTimestamp: Long = UNINITIALIZED_TIMESTAMP,
79+
expirationTimestamp: Long = UNINITIALIZED_TIMESTAMP
6680
) : this(
6781
id,
6882
singletonFields.associateWith { null },
@@ -73,17 +87,21 @@ data class RawEntity(
7387

7488
companion object {
7589
const val NO_REFERENCE_ID = "NO REFERENCE ID"
76-
const val NO_EXPIRATION: Long = -1
90+
const val UNINITIALIZED_TIMESTAMP: Long = -1
7791
}
7892
}
7993

8094
fun RawEntity(
8195
id: String,
8296
singletons: Map<FieldName, Referencable?>,
8397
collections: Map<FieldName, Set<Referencable>>,
98+
creationTimestamp: Long,
8499
expirationTimestamp: Long
85100
) = RawEntity(
86101
id,
87102
singletons,
88103
collections
89-
).also { it.expirationTimestamp = expirationTimestamp }
104+
).also {
105+
it.creationTimestamp = creationTimestamp
106+
it.expirationTimestamp = expirationTimestamp
107+
}

java/arcs/core/data/Ttl.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ sealed class Ttl(count: Int, val isInfinite: Boolean = false) {
3434
override fun hashCode(): Int = minutes.hashCode()
3535

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

4040
data class Minutes(val count: Int) : Ttl(count)

java/arcs/core/storage/handle/CollectionImpl.kt

+2
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ class CollectionImpl<T : Referencable>(
8888
*/
8989
suspend fun store(entity: T): Boolean {
9090
log.debug { "Storing: $entity" }
91+
@Suppress("GoodTime") // use Instant
92+
entity.creationTimestamp = requireNotNull(time).currentTimeMillis
9193
if (!Ttl.Infinite.equals(ttl)) {
9294
@Suppress("GoodTime") // use Instant
9395
entity.expirationTimestamp = ttl.calculateExpiration(time)

java/arcs/core/storage/handle/SingletonImpl.kt

+2
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ class SingletonImpl<T : Referencable>(
6464
* did not apply fully. Fetch the latest value and retry.
6565
* */
6666
suspend fun store(entity: T): Boolean {
67+
@Suppress("GoodTime") // use Instant
68+
entity.creationTimestamp = requireNotNull(time).currentTimeMillis
6769
if (!Ttl.Infinite.equals(ttl)) {
6870
@Suppress("GoodTime") // use Instant
6971
entity.expirationTimestamp = ttl.calculateExpiration(time)

java/arcs/sdk/android/dev/api/CollectionProxy.java

+9
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,15 @@ public Referencable unwrap() {
286286
return this;
287287
}
288288

289+
@Override
290+
public long getCreationTimestamp() {
291+
throw new AssertionError("ModelEntry::getCreationTimestamp not implemented");
292+
}
293+
294+
@Override
295+
public void setCreationTimestamp(long creationTimestamp) {
296+
throw new AssertionError("ModelEntry::setCreationTimestamp not implemented");
297+
}
289298

290299
@Override
291300
public long getExpirationTimestamp() {

javatests/arcs/core/storage/handle/CollectionIntegrationTest.kt

+8-3
Original file line numberDiff line numberDiff line change
@@ -170,20 +170,25 @@ class CollectionIntegrationTest {
170170
fun addElementsWithTtls() = runBlockingTest {
171171
val person = Person("John", 29, false)
172172
collectionA.store(person.toRawEntity())
173+
val creationTimestampA = collectionA.fetchAll().first().creationTimestamp
174+
assertThat(creationTimestampA).isNotEqualTo(RawEntity.UNINITIALIZED_TIMESTAMP)
173175
assertThat(collectionA.fetchAll().first().expirationTimestamp)
174-
.isEqualTo(RawEntity.NO_EXPIRATION)
176+
.isEqualTo(RawEntity.UNINITIALIZED_TIMESTAMP)
175177

176178
val collectionC = CollectionImpl("collectionC", storageProxy, null, null, Ttl.Days(2), TimeImpl())
177179
storageProxy.registerHandle(collectionC)
178180
assertThat(collectionC.store(person.toRawEntity())).isTrue()
179181
val entityC = collectionC.fetchAll().first()
180-
assertThat(entityC.expirationTimestamp).isGreaterThan(RawEntity.NO_EXPIRATION)
182+
assertThat(entityC.creationTimestamp).isGreaterThan(creationTimestampA)
183+
assertThat(entityC.expirationTimestamp).isGreaterThan(RawEntity.UNINITIALIZED_TIMESTAMP)
181184

182185
val collectionD = CollectionImpl("collectionD", storageProxy, null, null, Ttl.Minutes(1), TimeImpl())
183186
storageProxy.registerHandle(collectionD)
184187
assertThat(collectionD.store(person.toRawEntity())).isTrue()
185188
val entityD = collectionD.fetchAll().first()
186-
assertThat(entityD.expirationTimestamp).isGreaterThan(RawEntity.NO_EXPIRATION)
189+
assertThat(entityD.creationTimestamp).isGreaterThan(creationTimestampA)
190+
assertThat(entityD.creationTimestamp).isGreaterThan(entityC.creationTimestamp)
191+
assertThat(entityD.expirationTimestamp).isGreaterThan(RawEntity.UNINITIALIZED_TIMESTAMP)
187192
assertThat(entityC.expirationTimestamp).isGreaterThan(entityD.expirationTimestamp)
188193
}
189194

javatests/arcs/core/storage/handle/SingletonIntegrationTest.kt

+8-3
Original file line numberDiff line numberDiff line change
@@ -138,20 +138,25 @@ class SingletonIntegrationTest {
138138
fun addEntityWithTtl() = runBlockingTest {
139139
val person = Person("Jane", 29, false)
140140
assertThat(singletonA.store(person.toRawEntity())).isTrue()
141+
val creationTimestampA = requireNotNull(singletonA.fetch()).creationTimestamp;
142+
assertThat(creationTimestampA).isNotEqualTo(RawEntity.UNINITIALIZED_TIMESTAMP)
141143
assertThat(requireNotNull(singletonA.fetch()).expirationTimestamp)
142-
.isEqualTo(RawEntity.NO_EXPIRATION)
144+
.isEqualTo(RawEntity.UNINITIALIZED_TIMESTAMP)
143145

144146
val singletonC = SingletonImpl("singletonC", storageProxy, null, Ttl.Days(2), TimeImpl())
145147
storageProxy.registerHandle(singletonC)
146148
assertThat(singletonC.store(person.toRawEntity())).isTrue()
147149
val entityC = requireNotNull(singletonC.fetch())
148-
assertThat(entityC.expirationTimestamp).isGreaterThan(RawEntity.NO_EXPIRATION)
150+
assertThat(entityC.creationTimestamp).isGreaterThan(creationTimestampA)
151+
assertThat(entityC.expirationTimestamp).isGreaterThan(RawEntity.UNINITIALIZED_TIMESTAMP)
149152

150153
val singletonD = SingletonImpl("singletonD", storageProxy, null, Ttl.Minutes(1), TimeImpl())
151154
storageProxy.registerHandle(singletonD)
152155
assertThat(singletonD.store(person.toRawEntity())).isTrue()
153156
val entityD = requireNotNull(singletonD.fetch())
154-
assertThat(entityD.expirationTimestamp).isGreaterThan(RawEntity.NO_EXPIRATION)
157+
assertThat(entityD.creationTimestamp).isGreaterThan(creationTimestampA)
158+
assertThat(entityD.creationTimestamp).isGreaterThan(entityC.creationTimestamp)
159+
assertThat(entityD.expirationTimestamp).isGreaterThan(RawEntity.UNINITIALIZED_TIMESTAMP)
155160
assertThat(entityC.expirationTimestamp).isGreaterThan(entityD.expirationTimestamp)
156161
}
157162

src/runtime/manifest.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -829,7 +829,7 @@ ${e.message}
829829
for (const item of items.syntheticHandles) {
830830
const handle = recipe.newHandle();
831831
handle.fate = 'join';
832-
832+
833833
if (item.name) {
834834
assert(!items.byName.has(item.name), `duplicate handle name: ${item.name}`);
835835
handle.localName = item.name;

0 commit comments

Comments
 (0)