Commit 3ad41163 authored by juga's avatar juga
Browse files

docs: Add code design documentation

parent 321219c3
@startuml
class RelayList {
stem.Controller _controller
Lock _refresh_lock
int _last_refresh
list @p relays
list @p bad_exits
list @p exits
list @p non_exits
list @p authorities
bool _need_refresh()
_init_relays()
_refresh()
list _relays_with_flag(int flag)
list _relays_without_flag(int flag)
list exits_not_bad_can_exit_to_port(int port)
}
RelayList *-- Relay
class Relay {
stem.RouterStatusEntryV3 _from_ns
stem.RelayDescriptor _from_desc
str @p nickname
str @p fingerprint
list @p flags
ExitPolicy @p exit_policy
str @p address
str @p master_key_ed25519
int @p observed_bandwidth
int @p average_bandwidth
int @p burst_bandwidth
int @p consensus_bandwidth
int @p consensus_bandwidth_is_unmeasured
obj _from_ns(attr)
obj _from_desc(attr)
bool can_exit_to_port(int port)
bool is_exit_not_bad_allowing_port(int port)
}
class RelayPrioritizer {
int fresh_seconds
ResultDump result_dump
RelayList relay_list
bool measure_authorities
generator best_priority()
}
RelayPrioritizer *-- RelayList
RelayPrioritizer *-- ResultDump
Result ^-- ResultError
Result ^-- ResultSuccess
Result -- Destination
class Result {
Result.Relay _relay
list @p circ
str @p dest_url
str @p scanner
int @p time
str @p type
int @p version
str @p nickname
str @p fingerprint
str @p address
str @p master_key_ed25519
int @p relay_observed_bandwidth
int @p relay_average_bandwidth
int @p relay_burst_bandwidth
int @p consensus_bandwidth
int @p consensus_bandwidth_is_unmeasured
dict to_dict()
Result from_dict(dict d)
}
Result -- Relay
Result *-- Result.Relay
class Result.Relay {
str nickname
str fingerprint
str address
str master_key_ed25519
int observed_bandwidth
int average_bandwidth
int burst_bandwidth
int consensus_bandwidth
int consensus_bandwidth_is_unmeasured
}
class ResultError {
str @p msg
}
ResultError ^-- ResultErrorCircuit
class ResultErrorCircuit {
}
ResultError ^-- ResultErrorStream
class ResultSuccess {
list @p rtts
list @p downloads
}
ResultDump *-- Result
ResultDump -- Relay
class ResultDump {
dict data
int fresh_days
str datadir
Lock data_lock
Thread thread
Queue queue
store_result(Result result)
handle_result(Result result)
enter()
list results_for_relay(Relay relay)
}
class DestinationList {
list _rl
Destination next()
DestinationList @sm from_config(...)
}
DestinationList *-- Destination
class Destination {
str @p hostname
int @p port
str @p url
bool @p verify
bool is_usable()
Destination @sm from_config(str conf_section,int max_dl)
}
V3BWHeader -- Result
class V3BWHeader {
int timestamp
str version
str file_created
str latest_bandwidth
int num_lines
str software
str software_version
str generator_started
int number_eligible_relays
int minimum_number_eligible_relays
int number_consensus_relays
int percent_eligible_relays
int minimum_percent_eligible_relays
int @p num_lines
V3BWHeader @cm from_results(dict results)
add_stats(**kwargs)
int @sm earliest_bandwidth_from_results(dict results)
str @sm generator_started_from_file(dict results)
int @sm latest_bandwidth_from_results(dict results)
}
V3BWLine -- Result
class V3BWLine {
int bw
str node_id
str master_key_ed25519
str nick
int rtt
str time
int success
int error_stream
int error_circ
int error_misc
int bw_median
int bw_mean
int desc_bw_avg
int desc_bw_bur
int desc_bw_obs_last
int desc_bw_obs_mean
consensus_bandwidth
consensus_bandwidth_is_unmeasured
int @sm bw_mean_from_results(list results)
int @sm bw_median_from_results(list results)
int @sm desc_bw_obs_last_from_results(list results)
int @sm desc_bw_obs_mean_from_results(list results)
V3BWLine @cm from_results(list results)
str @sm last_time_from_results(list results)
dict @sm result_types_from_results(list results)
list @sm results_away_each_other(list results)
list @sm results_recent_than(list results)
}
V3BWFile *-- V3BWHeader
V3BWFile *-- V3BWLine
V3BWFile -- Result
class V3BWFile {
V3BWHeader header
list bw_lines
@p info_stats
bool @p is_min_perc
int @p max_bw
int @p mean_bw
int @p median_bw
int @p min_bw
int @p num
int @p sum_bw
V3BWFile @cm from_results(dict results, ...)
list @sm bw_kb(bw_lines)
list @sm bw_sbws_scale(bw_lines)
list @sm bw_torflow_scale(bw_lines)
bool @sm is_max_bw_diff_perc_reached(bw_lines)
(dict, bool) @sm measured_progress_stats(bw_lines)
int @sm read_number_consensus_relays(str consensus_path)
(list, list, list) to_plt()
list update_progress(bw_lines, ...)
warn_if_not_accurate_enough(bw_lines, ...)
tuple to_plt(...)
write(str output)
}
CircuitBuilder *-- RelayList
CircuitBuilder -- Relay
class CircuitBuilder {
set built_circuits
RelayList relay_list
list relays
Controller controller
int build_circuit()
void close_circuit()
}
CircuitBuilder ^-- GapsCircuitBuilder
class State {
get()
}
@enduml
\ No newline at end of file
Code design
=================
.. todo::
- Link to refactor proposal.
- Change this page when refactoring is implemented.
UML classes diagram
--------------------
.. image:: images/classes_original.*
:alt: UML classes diagram
`classes_original.svg <./_images/classes_original.svg>`_
Packages diagram
-----------------
.. image:: ./images/packages_sbws.*
:alt: packages diagram
`packages_sbws.svg <./_images/packages_sbws.svg>`_
scanner threads
----------------
- `TorEventListener`: the thread that runs Tor and listens for events.
- ResultDump: the thread that get the measurement results from a queue
every second.
- `multiprocessing.ThreadPool` starts 3 independent threads:
- workers_thread
- tasks_thread
- results_thread
- measurement threads: they execute :func:`sbws.core.scanner.measure_relay`
There'll be a maximum of 3 by default.
.. image:: images/threads.*
:alt: scanner threads
Critical sections
-----------------
Data types that are read or wrote from the threads.
.. image:: images/critical_sections.*
:alt: scanner critical sections
:height: 400px
:align: center
Call graph
--------------
Initialization calls to the moment where the measurement threads start.
.. image:: images/pycallgraph.png
:alt: call graph
:height: 400px
:align: center
`callgraph.png <./_images/pycallgraph.png>`_
UML diagrams
=============
Class Diagram
--------------------
.. image:: ./images/classes_sbws.*
`classes_sbws.svg <./_images/classes_sbws.svg>`_
Packages diagram
-----------------
.. image:: ./images/packages_sbws.*
`packages_sbws.svg <./_images/packages_sbws.svg>`_
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="266px" preserveAspectRatio="none" style="width:874px;height:266px;" version="1.1" viewBox="0 0 874 266" width="874px" zoomAndPan="magnify"><defs><filter height="300%" id="ft70fwu" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><ellipse cx="438.5" cy="20" fill="#000000" filter="url(#ft70fwu)" rx="10" ry="10" style="stroke: none; stroke-width: 1.0;"/><rect fill="#FEFECE" filter="url(#ft70fwu)" height="33.9688" rx="12.5" ry="12.5" style="stroke: #A80036; stroke-width: 1.5;" width="93" x="392" y="50"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="73" x="402" y="71.1387">MainThread</text><rect fill="#000000" filter="url(#ft70fwu)" height="6" rx="2.5" ry="2.5" style="stroke: #000000; stroke-width: 1.0;" width="857" x="10" y="103.9688"/><rect fill="#FEFECE" filter="url(#ft70fwu)" height="33.9688" rx="12.5" ry="12.5" style="stroke: #A80036; stroke-width: 1.5;" width="125" x="24" y="165.9688"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="105" x="34" y="187.1074">TorEventListener</text><rect fill="#FEFECE" filter="url(#ft70fwu)" height="33.9688" rx="12.5" ry="12.5" style="stroke: #A80036; stroke-width: 1.5;" width="95" x="177" y="165.9688"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="75" x="187" y="187.1074">ResultDump</text><rect fill="#FEFECE" filter="url(#ft70fwu)" height="33.9688" rx="12.5" ry="12.5" style="stroke: #A80036; stroke-width: 1.5;" width="117" x="300" y="165.9688"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="97" x="310" y="187.1074">workers_thread</text><rect fill="#FEFECE" filter="url(#ft70fwu)" height="33.9688" rx="12.5" ry="12.5" style="stroke: #A80036; stroke-width: 1.5;" width="102" x="445" y="165.9688"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="82" x="455" y="187.1074">tasks_thread</text><rect fill="#FEFECE" filter="url(#ft70fwu)" height="33.9688" rx="12.5" ry="12.5" style="stroke: #A80036; stroke-width: 1.5;" width="103" x="575" y="165.9688"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="83" x="585" y="187.1074">resutls_tread</text><rect fill="#FEFECE" filter="url(#ft70fwu)" height="33.9688" rx="12.5" ry="12.5" style="stroke: #A80036; stroke-width: 1.5;" width="111" x="730" y="177.9688"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="91" x="740" y="199.1074">measure_relay</text><polygon fill="#FEFECE" filter="url(#ft70fwu)" points="748.5,129.9688,822.5,129.9688,834.5,141.9688,822.5,153.9688,748.5,153.9688,736.5,141.9688,748.5,129.9688" style="stroke: #A80036; stroke-width: 1.5;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="74" x="748.5" y="145.7769">threads &lt; 3?</text><rect fill="#000000" filter="url(#ft70fwu)" height="6" rx="2.5" ry="2.5" style="stroke: #000000; stroke-width: 1.0;" width="857" x="10" y="253.9375"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="438.5" x2="438.5" y1="30" y2="50"/><polygon fill="#A80036" points="434.5,40,438.5,50,442.5,40,438.5,44" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="785.5" x2="785.5" y1="153.9688" y2="177.9688"/><polygon fill="#A80036" points="781.5,167.9688,785.5,177.9688,789.5,167.9688,785.5,171.9688" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="785.5" x2="785.5" y1="211.9375" y2="221.9375"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="785.5" x2="853" y1="221.9375" y2="221.9375"/><polygon fill="#A80036" points="849,192.9531,853,182.9531,857,192.9531,853,188.9531" style="stroke: #A80036; stroke-width: 1.5;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="853" x2="853" y1="141.9688" y2="221.9375"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="853" x2="834.5" y1="141.9688" y2="141.9688"/><polygon fill="#A80036" points="844.5,137.9688,834.5,141.9688,844.5,145.9688,840.5,141.9688" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="736.5" x2="718" y1="141.9688" y2="141.9688"/><polygon fill="#A80036" points="714,178.9531,718,188.9531,722,178.9531,718,182.9531" style="stroke: #A80036; stroke-width: 1.5;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="718" x2="718" y1="141.9688" y2="233.9375"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="718" x2="785.5" y1="233.9375" y2="233.9375"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="785.5" x2="785.5" y1="233.9375" y2="253.9375"/><polygon fill="#A80036" points="781.5,243.9375,785.5,253.9375,789.5,243.9375,785.5,247.9375" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="86.5" x2="86.5" y1="109.9688" y2="165.9688"/><polygon fill="#A80036" points="82.5,155.9688,86.5,165.9688,90.5,155.9688,86.5,159.9688" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="86.5" x2="86.5" y1="199.9375" y2="253.9375"/><polygon fill="#A80036" points="82.5,243.9375,86.5,253.9375,90.5,243.9375,86.5,247.9375" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="224.5" x2="224.5" y1="109.9688" y2="165.9688"/><polygon fill="#A80036" points="220.5,155.9688,224.5,165.9688,228.5,155.9688,224.5,159.9688" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="224.5" x2="224.5" y1="199.9375" y2="253.9375"/><polygon fill="#A80036" points="220.5,243.9375,224.5,253.9375,228.5,243.9375,224.5,247.9375" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="358.5" x2="358.5" y1="109.9688" y2="165.9688"/><polygon fill="#A80036" points="354.5,155.9688,358.5,165.9688,362.5,155.9688,358.5,159.9688" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="358.5" x2="358.5" y1="199.9375" y2="253.9375"/><polygon fill="#A80036" points="354.5,243.9375,358.5,253.9375,362.5,243.9375,358.5,247.9375" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="496" x2="496" y1="109.9688" y2="165.9688"/><polygon fill="#A80036" points="492,155.9688,496,165.9688,500,155.9688,496,159.9688" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="496" x2="496" y1="199.9375" y2="253.9375"/><polygon fill="#A80036" points="492,243.9375,496,253.9375,500,243.9375,496,247.9375" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="626.5" x2="626.5" y1="109.9688" y2="165.9688"/><polygon fill="#A80036" points="622.5,155.9688,626.5,165.9688,630.5,155.9688,626.5,159.9688" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="626.5" x2="626.5" y1="199.9375" y2="253.9375"/><polygon fill="#A80036" points="622.5,243.9375,626.5,253.9375,630.5,243.9375,626.5,247.9375" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="785.5" x2="785.5" y1="109.9688" y2="129.9688"/><polygon fill="#A80036" points="781.5,119.9688,785.5,129.9688,789.5,119.9688,785.5,123.9688" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="438.5" x2="438.5" y1="83.9688" y2="103.9688"/><polygon fill="#A80036" points="434.5,93.9688,438.5,103.9688,442.5,93.9688,438.5,97.9688" style="stroke: #A80036; stroke-width: 1.0;"/></g></svg>
\ No newline at end of file
@startuml
start
:MainThread;
fork
:TorEventListener;
fork again
:ResultDump;
fork again
:workers_thread;
fork again
:tasks_thread;
fork again
:resutls_tread;
fork again
while (threads < 3?)
:measure_relay;
endwhile
end fork
@enduml
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment