aboutsummaryrefslogtreecommitdiffstats
path: root/fnet/src/examples/timeout/timeout.cpp
blob: e0830c7cde12a292ecf8d5374fddcbe905a860b0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include <vespa/fnet/transport.h>
#include <vespa/fnet/signalshutdown.h>
#include <vespa/fnet/packetqueue.h>
#include <vespa/fnet/controlpacket.h>
#include <vespa/vespalib/util/signalhandler.h>
#include <vespa/vespalib/util/time.h>
#include <thread>

#include <vespa/log/log.h>
LOG_SETUP("timeout");

class Timeout : public FNET_Task
{
private:
  FNET_PacketQueue *_queue;

  Timeout(const Timeout &);
  Timeout &operator=(const Timeout &);

public:
  Timeout(FNET_Scheduler *scheduler,
          FNET_PacketQueue *queue)
    : FNET_Task(scheduler),
      _queue(queue)
  {}

     void PerformTask() override;
};


void
Timeout::PerformTask()
{
    _queue->QueuePacket(&FNET_ControlPacket::Timeout, FNET_Context());
}


class MyApp
{
public:
  int main(int argc, char **argv);
};


int
MyApp::main(int, char **)
{
  using clock = std::chrono::steady_clock;
  using ms_double = std::chrono::duration<double,std::milli>;

  ms_double                  ms;
  clock::time_point          t;
  FNET_PacketQueue           queue;
  FNET_Transport             transport;
  Timeout                    timeout(transport.GetScheduler(), &queue);
  transport.Start();

  // stable-state operation
  std::this_thread::sleep_for(100ms);

  FNET_Packet  *packet;
  FNET_Context  context;

  fprintf(stderr, "scheduling timeout in 1 seconds...\n");
  t = clock::now();
  timeout.Schedule(1.0); // timeout in 1 seconds

  std::this_thread::sleep_for(100ms);

  timeout.Unschedule(); // cancel timeout
  ms = (clock::now() - t);

  if (queue.GetPacketCnt_NoLock() == 0)
    fprintf(stderr, "timeout canceled; no timeout packet delivered\n");
  fprintf(stderr, "time since timeout was scheduled: %f ms\n", ms.count());

  fprintf(stderr, "scheduling timeout in 1 seconds...\n");
  t = clock::now();
  timeout.Schedule(1.0); // timeout in 1 seconds

  packet = queue.DequeuePacket(&context); // wait for timeout
  ms = (clock::now() - t);

  if (packet->IsTimeoutCMD())
    fprintf(stderr, "got timeout packet\n");
  fprintf(stderr, "time since timeout was scheduled: %f ms\n", ms.count());

  transport.ShutDown(true);
  return 0;
}


int main(int argc, char **argv) {
    vespalib::SignalHandler::PIPE.ignore();
    MyApp myapp;
    return myapp.main(argc, argv);
}