Commit c0514ca3f4379a68206d1856cbfe952b34b5e7be

Authored by Sergey Matvienko
Committed by GitHub
1 parent f2974532

Stats: do not persist empty stats (reducing event table size and disk IOPS) (#5554)

* stats: do not persist empty stats

* fixed license headers for stat actor and stat msg tests
... ... @@ -51,6 +51,9 @@ public class StatsActor extends ContextAwareActor {
51 51 }
52 52
53 53 public void onStatsPersistMsg(StatsPersistMsg msg) {
  54 + if (msg.isEmpty()) {
  55 + return;
  56 + }
54 57 Event event = new Event();
55 58 event.setEntityId(msg.getEntityId());
56 59 event.setTenantId(msg.getTenantId());
... ...
... ... @@ -37,4 +37,9 @@ public final class StatsPersistMsg implements TbActorMsg {
37 37 public MsgType getMsgType() {
38 38 return MsgType.STATS_PERSIST_MSG;
39 39 }
  40 +
  41 + public boolean isEmpty() {
  42 + return messagesProcessed == 0 && errorsOccurred == 0;
  43 + }
  44 +
40 45 }
... ...
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.actors.stats;
  17 +
  18 +import org.junit.jupiter.api.BeforeEach;
  19 +import org.junit.jupiter.api.Test;
  20 +import org.thingsboard.server.actors.ActorSystemContext;
  21 +import org.thingsboard.server.common.data.Event;
  22 +import org.thingsboard.server.common.data.id.TenantId;
  23 +import org.thingsboard.server.dao.event.EventService;
  24 +import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
  25 +
  26 +import static org.mockito.ArgumentMatchers.any;
  27 +import static org.mockito.BDDMockito.willReturn;
  28 +import static org.mockito.Mockito.mock;
  29 +import static org.mockito.Mockito.never;
  30 +import static org.mockito.Mockito.times;
  31 +import static org.mockito.Mockito.verify;
  32 +
  33 +class StatsActorTest {
  34 +
  35 + StatsActor statsActor;
  36 + ActorSystemContext actorSystemContext;
  37 + EventService eventService;
  38 + TbServiceInfoProvider serviceInfoProvider;
  39 +
  40 + @BeforeEach
  41 + void setUp() {
  42 + actorSystemContext = mock(ActorSystemContext.class);
  43 +
  44 + eventService = mock(EventService.class);
  45 + willReturn(eventService).given(actorSystemContext).getEventService();
  46 + serviceInfoProvider = mock(TbServiceInfoProvider.class);
  47 + willReturn(serviceInfoProvider).given(actorSystemContext).getServiceInfoProvider();
  48 +
  49 + statsActor = new StatsActor(actorSystemContext);
  50 + }
  51 +
  52 + @Test
  53 + void givenEmptyStatMessage_whenOnStatsPersistMsg_thenNoAction() {
  54 + StatsPersistMsg emptyStats = new StatsPersistMsg(0, 0, TenantId.SYS_TENANT_ID, TenantId.SYS_TENANT_ID);
  55 + statsActor.onStatsPersistMsg(emptyStats);
  56 + verify(actorSystemContext, never()).getEventService();
  57 + }
  58 +
  59 + @Test
  60 + void givenNonEmptyStatMessage_whenOnStatsPersistMsg_thenNoAction() {
  61 + statsActor.onStatsPersistMsg(new StatsPersistMsg(0, 1, TenantId.SYS_TENANT_ID, TenantId.SYS_TENANT_ID));
  62 + verify(eventService, times(1)).save(any(Event.class));
  63 + statsActor.onStatsPersistMsg(new StatsPersistMsg(1, 0, TenantId.SYS_TENANT_ID, TenantId.SYS_TENANT_ID));
  64 + verify(eventService, times(2)).save(any(Event.class));
  65 + statsActor.onStatsPersistMsg(new StatsPersistMsg(1, 1, TenantId.SYS_TENANT_ID, TenantId.SYS_TENANT_ID));
  66 + verify(eventService, times(3)).save(any(Event.class));
  67 + }
  68 +
  69 +}
... ...
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.actors.stats;
  17 +
  18 +import org.junit.jupiter.api.Test;
  19 +import org.thingsboard.server.common.data.id.TenantId;
  20 +
  21 +import static org.assertj.core.api.Assertions.assertThat;
  22 +
  23 +class StatsPersistMsgTest {
  24 +
  25 + @Test
  26 + void testIsEmpty() {
  27 + StatsPersistMsg emptyStats = new StatsPersistMsg(0, 0, TenantId.SYS_TENANT_ID, TenantId.SYS_TENANT_ID);
  28 + assertThat(emptyStats.isEmpty()).isTrue();
  29 + }
  30 +
  31 + @Test
  32 + void testNotEmpty() {
  33 + assertThat(new StatsPersistMsg(1, 0, TenantId.SYS_TENANT_ID, TenantId.SYS_TENANT_ID).isEmpty()).isFalse();
  34 + assertThat(new StatsPersistMsg(0, 1, TenantId.SYS_TENANT_ID, TenantId.SYS_TENANT_ID).isEmpty()).isFalse();
  35 + assertThat(new StatsPersistMsg(1, 1, TenantId.SYS_TENANT_ID, TenantId.SYS_TENANT_ID).isEmpty()).isFalse();
  36 + }
  37 +
  38 +}
... ...