Skip to content

Commit 5548fea

Browse files
authored
Add property's ttl (#48)
1 parent 32eae17 commit 5548fea

File tree

9 files changed

+133
-7
lines changed

9 files changed

+133
-7
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Release Notes.
88
### Features
99

1010
* Add mod revision check to write requests
11+
* Add TTL to property.
1112

1213
0.4.0
1314
------------------

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,23 @@ Property property = Property.create("default", "sw", "ui_template")
323323
this.client.apply(property); //created:false tagsNum:1
324324
```
325325

326+
The property supports setting TTL.
327+
328+
```java
329+
Property property = Property.create("default", "sw", "temp_date")
330+
.addTag(TagAndValue.newStringTag("state", "failed"))
331+
.ttl("30m")
332+
.build();
333+
this.client.apply(property); //created:false tagsNum:1 lease_id:1
334+
```
335+
The property's TTL can be extended by calling `Client.keepAliveProperty`,
336+
337+
```java
338+
this.client.keepAliveProperty(1); //lease_id:1
339+
```
340+
341+
The property's live time is reset to 30 minutes.
342+
326343
### Query
327344

328345
Property can be queried via `Client.findProperty`,

src/main/java/org/apache/skywalking/banyandb/v1/client/BanyanDBClient.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,16 @@ public PropertyStore.DeleteResult deleteProperty(String group, String name, Stri
544544
return store.delete(group, name, id, tags);
545545
}
546546

547+
/**
548+
* Keep alive the property
549+
*
550+
* @param leaseId lease id of the property
551+
*/
552+
public void keepAliveProperty(long leaseId) throws BanyanDBException {
553+
PropertyStore store = new PropertyStore(checkNotNull(this.channel));
554+
store.keepAlive(leaseId);
555+
}
556+
547557
/**
548558
* Bind index rule to the stream
549559
*

src/main/java/org/apache/skywalking/banyandb/v1/client/metadata/Property.java

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@
1919
package org.apache.skywalking.banyandb.v1.client.metadata;
2020

2121
import com.google.auto.value.AutoValue;
22+
import com.google.common.base.Strings;
2223
import com.google.common.collect.ImmutableList;
2324
import org.apache.skywalking.banyandb.model.v1.BanyandbModel;
2425
import org.apache.skywalking.banyandb.property.v1.BanyandbProperty;
2526
import org.apache.skywalking.banyandb.v1.client.TagAndValue;
27+
import org.apache.skywalking.banyandb.v1.client.util.IgnoreHashEquals;
2628
import org.apache.skywalking.banyandb.v1.client.util.TimeUtils;
2729

30+
import javax.annotation.Nullable;
2831
import java.time.ZonedDateTime;
2932
import java.util.ArrayList;
3033
import java.util.List;
@@ -35,19 +38,32 @@ public abstract class Property extends NamedSchema<BanyandbProperty.Property> {
3538

3639
public abstract ImmutableList<TagAndValue<?>> tags();
3740

41+
@Nullable
42+
public abstract String ttl();
43+
44+
@Nullable
45+
@IgnoreHashEquals
46+
public abstract Long leaseId();
47+
3848
@Override
3949
public BanyandbProperty.Property serialize() {
4050
List<BanyandbModel.Tag> tags = new ArrayList<>(this.tags().size());
4151
for (final TagAndValue<?> tagAndValue : this.tags()) {
4252
tags.add(tagAndValue.build());
4353
}
44-
return BanyandbProperty.Property.newBuilder()
54+
BanyandbProperty.Property.Builder builder = BanyandbProperty.Property.newBuilder()
4555
.setMetadata(BanyandbProperty.Metadata.newBuilder()
4656
.setId(id())
4757
.setContainer(buildMetadata())
4858
.build())
49-
.addAllTags(tags)
50-
.build();
59+
.addAllTags(tags);
60+
if (!Strings.isNullOrEmpty(ttl())) {
61+
builder.setTtl(ttl());
62+
}
63+
if (leaseId() != null) {
64+
builder.setLeaseId(leaseId());
65+
}
66+
return builder.build();
5167
}
5268

5369
public static Builder create(String group, String name, String id) {
@@ -59,6 +75,12 @@ static Property fromProtobuf(BanyandbProperty.Property pb) {
5975
pb.getMetadata().getContainer().getName(),
6076
pb.getMetadata().getId())
6177
.setUpdatedAt(TimeUtils.parseTimestamp(pb.getUpdatedAt()));
78+
if (!Strings.isNullOrEmpty(pb.getTtl())) {
79+
b.setTtl(pb.getTtl());
80+
}
81+
if (pb.getLeaseId() > 0) {
82+
b.setLeaseId(pb.getLeaseId());
83+
}
6284

6385
// build tag family spec
6486
for (int i = 0; i < pb.getTagsCount(); i++) {
@@ -85,6 +107,10 @@ public final Builder addTag(TagAndValue<?> tagAndValue) {
85107
return this;
86108
}
87109

110+
public abstract Builder setTtl(String ttl);
111+
112+
abstract Builder setLeaseId(long leaseId);
113+
88114
public abstract Property build();
89115
}
90116
}

src/main/java/org/apache/skywalking/banyandb/v1/client/metadata/PropertyStore.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public ApplyResult apply(Property payload, Strategy strategy) throws BanyanDBExc
5757
.build();
5858
BanyandbProperty.ApplyResponse resp = HandleExceptionsWith.callAndTranslateApiException(() ->
5959
this.stub.apply(r));
60-
return new AutoValue_PropertyStore_ApplyResult(resp.getCreated(), resp.getTagsNum());
60+
return new AutoValue_PropertyStore_ApplyResult(resp.getCreated(), resp.getTagsNum(), resp.getLeaseId());
6161
}
6262

6363
public DeleteResult delete(String group, String name, String id, String... tags) throws BanyanDBException {
@@ -115,6 +115,14 @@ public List<Property> list(String group, String name, List<String> ids, List<Str
115115
return resp.getPropertyList().stream().map(Property::fromProtobuf).collect(Collectors.toList());
116116
}
117117

118+
public void keepAlive(long leaseId) throws BanyanDBException {
119+
BanyandbProperty.KeepAliveRequest req = BanyandbProperty.KeepAliveRequest.newBuilder()
120+
.setLeaseId(leaseId)
121+
.build();
122+
HandleExceptionsWith.callAndTranslateApiException(() ->
123+
this.stub.keepAlive(req));
124+
}
125+
118126
public enum Strategy {
119127
MERGE, REPLACE
120128
}
@@ -124,6 +132,8 @@ public abstract static class ApplyResult {
124132
public abstract boolean created();
125133

126134
public abstract int tagsNum();
135+
136+
public abstract long leaseId();
127137
}
128138

129139
@AutoValue

src/main/proto/banyandb/v1/banyandb-property.proto

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ message Metadata {
3434
string id = 2;
3535
}
3636

37+
3738
// Property stores the user defined data
3839
message Property {
3940
// metadata is the identity of a property
@@ -42,6 +43,13 @@ message Property {
4243
repeated model.v1.Tag tags = 2;
4344
// updated_at indicates when the property is updated
4445
google.protobuf.Timestamp updated_at = 3;
46+
// readonly. lease_id is the ID of the lease that attached to key.
47+
int64 lease_id = 4;
48+
// ttl indicates the time to live of the property.
49+
// It's a string in the format of "1h", "2m", "3s", "1500ms".
50+
// It defaults to 0s, which means the property never expires.
51+
// The minimum allowed ttl is 1s.
52+
string ttl = 5;
4553
}
4654

4755
message ApplyRequest {
@@ -60,6 +68,7 @@ message ApplyResponse {
6068
// True: the property is absent. False: the property existed.
6169
bool created = 1;
6270
uint32 tags_num = 2;
71+
int64 lease_id = 3;
6372
}
6473

6574
message DeleteRequest {
@@ -91,10 +100,17 @@ message ListResponse {
91100
repeated banyandb.property.v1.Property property = 1;
92101
}
93102

103+
message KeepAliveRequest {
104+
int64 lease_id = 1;
105+
}
106+
107+
message KeepAliveResponse {}
108+
94109
service PropertyService {
95110
// Apply creates a property if it's absent, or update a existed one based on a strategy.
96111
rpc Apply(ApplyRequest) returns (ApplyResponse);
97112
rpc Delete(DeleteRequest) returns (DeleteResponse);
98113
rpc Get(GetRequest) returns (GetResponse);
99114
rpc List(ListRequest) returns (ListResponse);
115+
rpc KeepAlive(KeepAliveRequest) returns (KeepAliveResponse);
100116
}

src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBClientTestCI.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
public class BanyanDBClientTestCI {
3131
private static final String REGISTRY = "ghcr.io";
3232
private static final String IMAGE_NAME = "apache/skywalking-banyandb";
33-
private static final String TAG = "9552688d60f055f6bb539a91464e8b1db77e7309";
33+
private static final String TAG = "f3abf75e66695f3c9fcae3138ad55e7a9d74f39a";
3434

3535
private static final String IMAGE = REGISTRY + "/" + IMAGE_NAME + ":" + TAG;
3636

src/test/java/org/apache/skywalking/banyandb/v1/client/ITBanyanDBPropertyTests.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.apache.skywalking.banyandb.v1.client.grpc.exception.BanyanDBException;
2323
import org.apache.skywalking.banyandb.v1.client.metadata.Group;
2424
import org.apache.skywalking.banyandb.v1.client.metadata.Property;
25+
import org.apache.skywalking.banyandb.v1.client.metadata.PropertyStore;
2526
import org.junit.After;
2627
import org.junit.Assert;
2728
import org.junit.Before;
@@ -128,4 +129,16 @@ public void test_PropertyList() throws BanyanDBException {
128129
});
129130
}
130131

132+
@Test
133+
public void test_PropertyKeepAlive() throws BanyanDBException {
134+
Property property = Property.create("default", "sw", "id1")
135+
.setTtl("30m")
136+
.addTag(TagAndValue.newStringTag("name", "bar"))
137+
.build();
138+
PropertyStore.ApplyResult resp = this.client.apply(property);
139+
Assert.assertTrue(resp.created());
140+
Assert.assertTrue(resp.leaseId() > 0);
141+
this.client.keepAliveProperty(resp.leaseId());
142+
}
143+
131144
}

src/test/java/org/apache/skywalking/banyandb/v1/client/metadata/PropertyStoreTest.java

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
package org.apache.skywalking.banyandb.v1.client.metadata;
2020

21+
import com.google.common.base.Strings;
2122
import io.grpc.stub.StreamObserver;
2223
import org.apache.skywalking.banyandb.property.v1.BanyandbProperty;
2324
import org.apache.skywalking.banyandb.property.v1.PropertyServiceGrpc;
@@ -32,8 +33,10 @@
3233
import java.io.IOException;
3334
import java.time.ZonedDateTime;
3435
import java.util.HashMap;
36+
import java.util.HashSet;
3537
import java.util.List;
3638
import java.util.Map;
39+
import java.util.Set;
3740

3841
import static org.mockito.AdditionalAnswers.delegatesTo;
3942
import static org.mockito.Mockito.mock;
@@ -43,6 +46,8 @@ public class PropertyStoreTest extends AbstractBanyanDBClientTest {
4346

4447
private Map<String, BanyandbProperty.Property> memory;
4548

49+
private Set<Long> leasePool;
50+
4651
private final PropertyServiceGrpc.PropertyServiceImplBase propertyServiceImpl = mock(PropertyServiceGrpc.PropertyServiceImplBase.class, delegatesTo(
4752
new PropertyServiceGrpc.PropertyServiceImplBase() {
4853
@Override
@@ -53,10 +58,16 @@ public void apply(BanyandbProperty.ApplyRequest request, StreamObserver<Banyandb
5358
String key = format(p.getMetadata());
5459
BanyandbProperty.Property v = memory.get(key);
5560
memory.put(format(p.getMetadata()), p);
61+
BanyandbProperty.ApplyResponse.Builder builder = BanyandbProperty.ApplyResponse.newBuilder().setTagsNum(p.getTagsCount());
62+
if (!Strings.isNullOrEmpty(p.getTtl())) {
63+
long leaseId = System.currentTimeMillis();
64+
leasePool.add(leaseId);
65+
builder.setLeaseId(leaseId);
66+
}
5667
if (v == null) {
57-
responseObserver.onNext(BanyandbProperty.ApplyResponse.newBuilder().setCreated(true).setTagsNum(p.getTagsCount()).build());
68+
responseObserver.onNext(builder.setCreated(true).build());
5869
} else {
59-
responseObserver.onNext(BanyandbProperty.ApplyResponse.newBuilder().setCreated(false).setTagsNum(p.getTagsCount()).build());
70+
responseObserver.onNext(builder.setCreated(false).build());
6071
}
6172
responseObserver.onCompleted();
6273
}
@@ -80,12 +91,22 @@ public void list(BanyandbProperty.ListRequest request, StreamObserver<BanyandbPr
8091
responseObserver.onNext(BanyandbProperty.ListResponse.newBuilder().addAllProperty(memory.values()).build());
8192
responseObserver.onCompleted();
8293
}
94+
95+
public void keepAlive(BanyandbProperty.KeepAliveRequest request, StreamObserver<BanyandbProperty.KeepAliveResponse> responseObserver) {
96+
if (!leasePool.contains(request.getLeaseId())) {
97+
responseObserver.onError(new RuntimeException("lease not found"));
98+
} else {
99+
responseObserver.onNext(BanyandbProperty.KeepAliveResponse.newBuilder().build());
100+
}
101+
responseObserver.onCompleted();
102+
}
83103
}));
84104

85105
@Before
86106
public void setUp() throws IOException {
87107
super.setUp(bindService(propertyServiceImpl));
88108
this.memory = new HashMap<>();
109+
this.leasePool = new HashSet<>();
89110
this.store = new PropertyStore(this.channel);
90111
}
91112

@@ -138,6 +159,18 @@ public void testPropertyStore_createAndDelete() throws BanyanDBException {
138159
Assert.assertEquals(0, memory.size());
139160
}
140161

162+
@Test
163+
public void testPropertyStore_keepAlive() throws BanyanDBException {
164+
Property property = Property.create("default", "sw", "ui_template")
165+
.addTag(TagAndValue.newStringTag("name", "hello"))
166+
.setTtl("30m")
167+
.build();
168+
PropertyStore.ApplyResult resp = this.store.apply(property);
169+
Assert.assertTrue(resp.created());
170+
Assert.assertTrue(resp.leaseId() > 0);
171+
this.store.keepAlive(resp.leaseId());
172+
}
173+
141174
static String format(BanyandbProperty.Metadata metadata) {
142175
return metadata.getContainer().getGroup() + ":" + metadata.getContainer().getName() + "/" + metadata.getId();
143176
}

0 commit comments

Comments
 (0)