aboutsummaryrefslogtreecommitdiffstats
path: root/fnet/src/examples/timeout/timeout.cpp
blob: 23dfbeb9070d8ae9d51054d58031323c5a891235 (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 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include <vespa/fnet/fnet.h>
#include <vespa/fastos/app.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 FastOS_Application
{
public:
  int Main() override;
};


int
MyApp::Main()
{
  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;
  FastOS_ThreadPool          pool(65000);
  FNET_Transport             transport;
  Timeout                    timeout(transport.GetScheduler(), &queue);
  transport.Start(&pool);

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

  FNET_Packet  *packet;
  FNET_Context  context;

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

  std::this_thread::sleep_for(1s);

  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 2 seconds...\n");
  t = clock::now();
  timeout.Schedule(2.0); // timeout in 2 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);
  pool.Close();
  return 0;
}


int
main(int argc, char **argv)
{
  MyApp myapp;
  return myapp.Entry(argc, argv);
}