1#ifndef XRPL_RESOURCE_LOGIC_H_INCLUDED
2#define XRPL_RESOURCE_LOGIC_H_INCLUDED
4#include <xrpl/basics/Log.h>
5#include <xrpl/basics/UnorderedContainers.h>
6#include <xrpl/basics/chrono.h>
7#include <xrpl/beast/clock/abstract_clock.h>
8#include <xrpl/beast/insight/Insight.h>
9#include <xrpl/beast/utility/PropertyStream.h>
10#include <xrpl/beast/utility/instrumentation.h>
11#include <xrpl/json/json_value.h>
12#include <xrpl/protocol/jss.h>
13#include <xrpl/resource/Fees.h>
14#include <xrpl/resource/Gossip.h>
15#include <xrpl/resource/detail/Import.h>
34 warn = collector->make_meter(
"warn");
35 drop = collector->make_meter(
"drop");
94 Entry* entry(
nullptr);
103 entry = &resultIt->second;
104 entry->key = &resultIt->first;
106 if (entry->refcount == 1)
124 Entry* entry(
nullptr);
133 entry = &resultIt->second;
134 entry->key = &resultIt->first;
136 if (entry->refcount == 1)
157 Entry* entry(
nullptr);
166 entry = &resultIt->second;
167 entry->key = &resultIt->first;
169 if (entry->refcount == 1)
199 int localBalance = inboundEntry.local_balance.value(now);
200 if ((localBalance + inboundEntry.remote_balance) >= threshold)
204 entry[jss::local] = localBalance;
205 entry[jss::remote] = inboundEntry.remote_balance;
206 entry[jss::type] =
"inbound";
211 int localBalance = outboundEntry.local_balance.value(now);
212 if ((localBalance + outboundEntry.remote_balance) >= threshold)
216 entry[jss::local] = localBalance;
217 entry[jss::remote] = outboundEntry.remote_balance;
218 entry[jss::type] =
"outbound";
221 for (
auto& adminEntry :
admin_)
223 int localBalance = adminEntry.local_balance.value(now);
224 if ((localBalance + adminEntry.remote_balance) >= threshold)
228 entry[jss::local] = localBalance;
229 entry[jss::remote] = adminEntry.remote_balance;
230 entry[jss::type] =
"admin";
250 item.
balance = inboundEntry.local_balance.value(now);
254 gossip.
items.push_back(item);
278 Import& next(resultIt->second);
280 next.items.reserve(gossip.
items.size());
282 for (
auto const& gossipItem : gossip.
items)
285 item.
balance = gossipItem.balance;
288 next.items.push_back(item);
298 next.items.reserve(gossip.
items.size());
299 for (
auto const& gossipItem : gossip.
items)
302 item.
balance = gossipItem.balance;
305 next.items.push_back(item);
308 Import& prev(resultIt->second);
309 for (
auto& item : prev.items)
311 item.consumer.entry().remote_balance -= item.balance;
332 if (iter->whenExpires <= elapsed)
348 Import&
import(iter->second);
349 if (iter->second.whenExpires <= elapsed)
351 for (
auto item_iter(
import.items.begin());
352 item_iter !=
import.items.end();
355 item_iter->consumer.entry().remote_balance -=
385 Entry& entry(iter->second);
388 "ripple::Resource::Logic::erase : entry not used");
404 if (--entry.refcount == 0)
408 switch (entry.key->kind)
422 "ripple::Resource::Logic::release : invalid entry "
439 feeLogAsWarn > feeLogAsInfo && feeLogAsInfo > feeLogAsDebug &&
444 if (cost >= feeLogAsWarn)
445 return journal.warn();
446 if (cost >= feeLogAsInfo)
447 return journal.info();
448 if (cost >= feeLogAsDebug)
449 return journal.debug();
450 return journal.trace();
453 if (!context.empty())
454 context =
" (" + context +
")";
460 <<
"Charging " << entry <<
" for " << fee << context;
467 if (entry.isUnlimited())
474 elapsed != entry.lastWarningTime)
478 entry.lastWarningTime = elapsed;
491 if (entry.isUnlimited())
497 int const balance(entry.balance(now));
501 <<
"Consumer entry " << entry <<
" dropped with balance "
529 for (
auto& entry : list)
532 if (entry.refcount != 0)
533 item[
"count"] = entry.refcount;
534 item[
"name"] = entry.to_string();
535 item[
"balance"] = entry.balance(now);
536 if (entry.remote_balance != 0)
537 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