proxygen
ByteEventTracker.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-present, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree. An additional grant
7  * of patent rights can be found in the PATENTS file in the same directory.
8  *
9  */
11 
13 #include <string>
14 
15 using std::string;
16 using std::vector;
17 
18 namespace proxygen {
19 
22 }
23 
25  byteEvents_ = std::move(other.byteEvents_);
26 }
27 
28 // The purpose of self is to represent shared ownership during
29 // processByteEvents. This allows the owner to release ownership of the tracker
30 // from a callback without causing problems
31 bool ByteEventTracker::processByteEvents(std::shared_ptr<ByteEventTracker> self,
32  uint64_t bytesWritten) {
33  bool advanceEOM = false;
34 
35  while (!byteEvents_.empty() &&
36  (byteEvents_.front().byteOffset_ <= bytesWritten)) {
37  ByteEvent& event = byteEvents_.front();
38  int64_t latency;
39  auto txn = event.getTransaction();
40 
41  switch (event.eventType_) {
43  txn->onEgressHeaderFirstByte();
44  break;
46  txn->onEgressBodyFirstByte();
47  break;
49  txn->onEgressBodyLastByte();
50  if (callback_) {
51  callback_->onLastByteEvent(txn, event.byteOffset_, event.eomTracked_);
52  }
53  advanceEOM = true;
54  break;
56  txn->onEgressTrackedByte();
57  break;
59  latency = event.getLatency();
60  if (callback_) {
61  callback_->onPingReplyLatency(latency);
62  }
63  break;
64  }
65 
66  VLOG(5) << " removing ByteEvent " << event;
67  // explicitly remove from the list, in case delete event triggers a
68  // callback that would absorb this ByteEventTracker.
69  event.listHook.unlink();
70  delete &event;
71  }
72 
73  if (advanceEOM) {
75  }
76  return self.use_count() == 1;
77 }
78 
80  size_t numEvents = 0;
81  // everything is dead from here on, let's just drop all extra refs to txns
82  while (!byteEvents_.empty()) {
83  delete &byteEvents_.front();
84  ++numEvents;
85  }
86  return numEvents;
87 }
88 
90  HTTPTransaction* txn,
91  uint64_t byteNo) noexcept {
92  VLOG(5) << " adding last byte event for " << byteNo;
94  byteNo, ByteEvent::LAST_BYTE, txn);
95  byteEvents_.push_back(*event);
96 }
97 
99  HTTPTransaction* txn,
100  uint64_t byteNo) noexcept {
101  VLOG(5) << " adding tracked byte event for " << byteNo;
103  byteNo, ByteEvent::TRACKED_BYTE, txn);
104  byteEvents_.push_back(*event);
105 }
106 
108  TimePoint timestamp,
109  uint64_t bytesScheduled) {
110  // register a byte event on ping reply sent, and adjust the byteOffset_
111  // for others by one ping size
112  uint64_t offset = bytesScheduled + pingSize;
113  auto i = byteEvents_.rbegin();
114  for (; i != byteEvents_.rend(); ++i) {
115  if (i->byteOffset_ > bytesScheduled) {
116  VLOG(5) << "pushing back ByteEvent from " << *i << " to "
117  << ByteEvent(i->byteOffset_ + pingSize, i->eventType_);
118  i->byteOffset_ += pingSize;
119  } else {
120  break; // the rest of the events are already scheduled
121  }
122  }
123 
124  ByteEvent* be = new PingByteEvent(offset, timestamp);
125  if (i == byteEvents_.rend()) {
126  byteEvents_.push_front(*be);
127  } else if (i == byteEvents_.rbegin()) {
128  byteEvents_.push_back(*be);
129  } else {
130  --i;
131  CHECK_GT(i->byteOffset_, bytesScheduled);
132  byteEvents_.insert(i.base(), *be);
133  }
134 }
135 
137  HTTPTransaction* txn) {
138  byteEvents_.push_back(
140  offset, ByteEvent::FIRST_BYTE,
141  txn));
142 }
143 
145  HTTPTransaction* txn) {
146  // onWriteSuccess() is called after the entire header has been written.
147  // It does not catch partial write case.
148  byteEvents_.push_back(
149  *new TransactionByteEvent(offset,
151  txn));
152 }
153 
154 } // proxygen
void addFirstBodyByteEvent(uint64_t offset, HTTPTransaction *txn)
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
virtual void addLastByteEvent(HTTPTransaction *txn, uint64_t byteNo) noexcept
requires E e noexcept(noexcept(s.error(std::move(e))))
void addPingByteEvent(size_t pingSize, TimePoint timestamp, uint64_t bytesScheduled)
virtual void onLastByteEvent(HTTPTransaction *txn, uint64_t offset, bool eomTracked) noexcept=0
virtual bool processByteEvents(std::shared_ptr< ByteEventTracker > self, uint64_t bytesWritten)
virtual void onPingReplyLatency(int64_t latency) noexcept=0
SteadyClock::time_point TimePoint
Definition: Time.h:25
virtual void addFirstHeaderByteEvent(uint64_t offset, HTTPTransaction *txn)
const char * string
Definition: Conv.cpp:212
virtual void absorb(ByteEventTracker &&other)
virtual size_t drainByteEvents()
virtual void addTrackedByteEvent(HTTPTransaction *txn, uint64_t byteNo) noexcept
folly::IntrusiveList< ByteEvent,&ByteEvent::listHook > byteEvents_