20#ifndef RIPPLE_RESOURCE_LOGIC_H_INCLUDED
21#define RIPPLE_RESOURCE_LOGIC_H_INCLUDED
23#include <xrpl/basics/Log.h>
24#include <xrpl/basics/UnorderedContainers.h>
25#include <xrpl/basics/chrono.h>
26#include <xrpl/beast/clock/abstract_clock.h>
27#include <xrpl/beast/insight/Insight.h>
28#include <xrpl/beast/utility/PropertyStream.h>
29#include <xrpl/beast/utility/instrumentation.h>
30#include <xrpl/json/json_value.h>
31#include <xrpl/protocol/jss.h>
32#include <xrpl/resource/Fees.h>
33#include <xrpl/resource/Gossip.h>
34#include <xrpl/resource/detail/Import.h>
53 warn = collector->make_meter(
"warn");
54 drop = collector->make_meter(
"drop");
113 Entry* entry(
nullptr);
118 std::piecewise_construct,
122 entry = &resultIt->second;
123 entry->key = &resultIt->first;
125 if (entry->refcount == 1)
143 Entry* entry(
nullptr);
148 std::piecewise_construct,
152 entry = &resultIt->second;
153 entry->key = &resultIt->first;
155 if (entry->refcount == 1)
176 Entry* entry(
nullptr);
181 std::piecewise_construct,
185 entry = &resultIt->second;
186 entry->key = &resultIt->first;
188 if (entry->refcount == 1)
218 int localBalance = inboundEntry.local_balance.value(now);
219 if ((localBalance + inboundEntry.remote_balance) >= threshold)
223 entry[jss::local] = localBalance;
224 entry[jss::remote] = inboundEntry.remote_balance;
225 entry[jss::type] =
"inbound";
230 int localBalance = outboundEntry.local_balance.value(now);
231 if ((localBalance + outboundEntry.remote_balance) >= threshold)
235 entry[jss::local] = localBalance;
236 entry[jss::remote] = outboundEntry.remote_balance;
237 entry[jss::type] =
"outbound";
240 for (
auto& adminEntry :
admin_)
242 int localBalance = adminEntry.local_balance.value(now);
243 if ((localBalance + adminEntry.remote_balance) >= threshold)
247 entry[jss::local] = localBalance;
248 entry[jss::remote] = adminEntry.remote_balance;
249 entry[jss::type] =
"admin";
269 item.
balance = inboundEntry.local_balance.value(now);
273 gossip.
items.push_back(item);
289 std::piecewise_construct,
297 Import& next(resultIt->second);
299 next.items.reserve(gossip.
items.size());
301 for (
auto const& gossipItem : gossip.
items)
304 item.
balance = gossipItem.balance;
307 next.items.push_back(item);
317 next.items.reserve(gossip.
items.size());
318 for (
auto const& gossipItem : gossip.
items)
321 item.
balance = gossipItem.balance;
324 next.items.push_back(item);
327 Import& prev(resultIt->second);
328 for (
auto& item : prev.items)
330 item.consumer.entry().remote_balance -= item.balance;
351 if (iter->whenExpires <= elapsed)
367 Import&
import(iter->second);
368 if (iter->second.whenExpires <= elapsed)
370 for (
auto item_iter(
import.items.begin());
371 item_iter !=
import.items.end();
374 item_iter->consumer.entry().remote_balance -=
404 Entry& entry(iter->second);
407 "ripple::Resource::Logic::erase : entry not used");
423 if (--entry.refcount == 0)
427 switch (entry.key->kind)
440 "ripple::Resource::Logic::release : invalid entry "
456 feeLogAsWarn > feeLogAsInfo && feeLogAsInfo > feeLogAsDebug &&
461 if (cost >= feeLogAsWarn)
462 return journal.warn();
463 if (cost >= feeLogAsInfo)
464 return journal.info();
465 if (cost >= feeLogAsDebug)
466 return journal.debug();
467 return journal.trace();
470 if (!context.empty())
471 context =
" (" + context +
")";
477 <<
"Charging " << entry <<
" for " << fee << context;
484 if (entry.isUnlimited())
491 elapsed != entry.lastWarningTime)
495 entry.lastWarningTime = elapsed;
508 if (entry.isUnlimited())
514 int const balance(entry.balance(now));
518 <<
"Consumer entry " << entry <<
" dropped with balance "
546 for (
auto& entry : list)
549 if (entry.refcount != 0)
550 item[
"count"] = entry.refcount;
551 item[
"name"] = entry.to_string();
552 item[
"balance"] = entry.balance(now);
553 if (entry.remote_balance != 0)
554 item[
"remote_balance"] = entry.remote_balance;
A version-independent IP address and port combination.
Address const & address() const
Returns the address portion of this endpoint.
Endpoint at_port(Port port) const
Returns a new Endpoint with a different port.
A generic endpoint for log messages.
iterator iterator_to(T &element) const noexcept
Obtain an iterator from an element.
iterator push_back(T &element) noexcept
Append an element at the end of the list.
iterator begin() noexcept
Obtain an iterator to the beginning of the list.
iterator end() noexcept
Obtain a iterator to the end of the list.
size_type size() const noexcept
Returns the number of elements in the list.
iterator erase(iterator pos) noexcept
Remove an element.
typename Clock::time_point time_point
virtual time_point now() const =0
Returns the current time.
A metric for measuring an integral value.
int value_type
The type used to hold a consumption charge.
value_type cost() const
Return the cost of the charge in Resource::Manager units.
An endpoint that consumes resources.
Consumer newInboundEndpoint(beast::IP::Endpoint const &address)
void importConsumers(std::string const &origin, Gossip const &gossip)
void acquire(Entry &entry)
EntryIntrusiveList admin_
Consumer newUnlimitedEndpoint(beast::IP::Endpoint const &address)
Create endpoint that should not have resource limits applied.
EntryIntrusiveList inactive_
void onWrite(beast::PropertyStream::Map &map)
EntryIntrusiveList outbound_
bool disconnect(Entry &entry)
Json::Value getJson(int threshold)
Returns a Json::objectValue.
Logic(beast::insight::Collector::ptr const &collector, clock_type &clock, beast::Journal journal)
Consumer newOutboundEndpoint(beast::IP::Endpoint const &address)
std::recursive_mutex lock_
Disposition charge(Entry &entry, Charge const &fee, std::string context={})
void writeList(clock_type::time_point const now, beast::PropertyStream::Set &items, EntryIntrusiveList &list)
void erase(Table::iterator iter)
int balance(Entry &entry)
EntryIntrusiveList inbound_
void release(Entry &entry)
static Disposition disposition(int balance)
@ objectValue
object value (collection of name/value pairs).
std::chrono::seconds constexpr gossipExpirationSeconds
Disposition
The disposition of a consumer after applying a load charge.
@ warn
Consumer should be disconnected for excess consumption.
std::chrono::seconds constexpr secondsUntilExpiration
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
beast::abstract_clock< std::chrono::steady_clock > Stopwatch
A clock for measuring elapsed time.
Describes a single consumer.
beast::IP::Endpoint address
Data format for exchanging consumption information across peers.
std::vector< Item > items
A set of imported consumer data from a gossip origin.
Stats(beast::insight::Collector::ptr const &collector)
beast::insight::Meter warn
beast::insight::Meter drop