Module: QuartzTorrent
- Defined in:
- lib/quartz_torrent/metainfopiecestate.rb,
lib/quartz_torrent/log.rb,
lib/quartz_torrent/peer.rb,
lib/quartz_torrent/rate.rb,
lib/quartz_torrent/util.rb,
lib/quartz_torrent/alarm.rb,
lib/quartz_torrent/magnet.rb,
lib/quartz_torrent/peermsg.rb,
lib/quartz_torrent/reactor.rb,
lib/quartz_torrent/bitfield.rb,
lib/quartz_torrent/metainfo.rb,
lib/quartz_torrent/extension.rb,
lib/quartz_torrent/formatter.rb,
lib/quartz_torrent/ratelimit.rb,
lib/quartz_torrent/regionmap.rb,
lib/quartz_torrent/blockstate.rb,
lib/quartz_torrent/peerclient.rb,
lib/quartz_torrent/peerholder.rb,
lib/quartz_torrent/filemanager.rb,
lib/quartz_torrent/memprofiler.rb,
lib/quartz_torrent/peermanager.rb,
lib/quartz_torrent/timermanager.rb,
lib/quartz_torrent/torrentqueue.rb,
lib/quartz_torrent/udptrackermsg.rb,
lib/quartz_torrent/classifiedpeers.rb,
lib/quartz_torrent/udptrackerdriver.rb,
lib/quartz_torrent/httptrackerdriver.rb,
lib/quartz_torrent/interruptiblesleep.rb,
lib/quartz_torrent/peermsgserialization.rb,
lib/quartz_torrent/piecemanagerrequestmetadata.rb
Overview
This class is used when we don’t have the info struct for the torrent (no .torrent file) and must download it piece by piece from peers. It keeps track of the pieces we have.
When a piece is requested from a peer and that peer responds with a reject saying it doesn’t have that metainfo piece, we take a simple approach and mark that peer as bad, and don’t request any more pieces from that peer even though they may have other pieces. This simplifies the code.
Defined Under Namespace
Classes: Alarm, Alarms, Bitfield, BitfieldMessage, BlockInfo, BlockState, Cancel, Choke, ClassifiedPeers, EmptyBitfield, Extended, ExtendedHandshake, ExtendedMetaInfo, Extension, FileRegion, Formatter, Handler, Have, HttpTrackerDriver, IOInfo, IOManager, IncompletePiece, Interested, InterruptibleSleep, IoFacade, KeepAlive, LogManager, MagnetURI, ManagePeersResult, MemProfiler, Metainfo, MetainfoPieceState, OutputBuffer, Peer, PeerClient, PeerClientHandler, PeerHandshake, PeerHolder, PeerManager, PeerRequest, PeerWireMessage, PeerWireMessageSerializer, Piece, PieceIO, PieceManager, PieceManagerRequestMetadata, PieceMapper, Rate, RateLimit, Reactor, ReadRequestMetadata, RegionMap, Request, RequestedBlock, TimerManager, TorrentData, TorrentDataDelegate, TorrentQueue, TrackerClient, TrackerDriver, UdpTrackerAnnounceRequest, UdpTrackerAnnounceResponse, UdpTrackerConnectRequest, UdpTrackerConnectResponse, UdpTrackerDriver, UdpTrackerMessage, UdpTrackerRequest, UdpTrackerResponse, Unchoke, Uninterested, WriteOnlyIoFacade
Constant Summary collapse
- SYSCALL_GETTID =
This is Linux specific: system call number for gettid
224
Class Method Summary collapse
-
.arrayShuffleRange!(array, start, length) ⇒ Object
Shuffle the subset of elements in the given array between start and start+length-1 inclusive.
-
.bytesToHex(v, addSpaces = nil) ⇒ Object
Return a hex string representing the bytes in the passed string.
-
.hexToBytes(v) ⇒ Object
Given a hex string representing a sequence of bytes, convert it the the original bytes.
-
.initThread(name) ⇒ Object
Method to set a few thread-local variables useful in debugging.
-
.logBacktraces(io = nil) ⇒ Object
Log backtraces of all threads currently running.
-
.setThreadLwpid(thread = nil) ⇒ Object
Store Linux Lightweight process ids (LWPID) on each thread.
Class Method Details
.arrayShuffleRange!(array, start, length) ⇒ Object
Shuffle the subset of elements in the given array between start and start+length-1 inclusive.
36 37 38 39 40 41 42 43 44 |
# File 'lib/quartz_torrent/util.rb', line 36 def self.arrayShuffleRange!(array, start, length) raise "Invalid range" if start + length > array.size (start+length).downto(start+1) do |i| r = start + rand(i-start) array[r], array[i-1] = array[i-1], array[r] end true end |
.bytesToHex(v, addSpaces = nil) ⇒ Object
Return a hex string representing the bytes in the passed string.
19 20 21 22 23 24 25 26 27 28 |
# File 'lib/quartz_torrent/util.rb', line 19 def self.bytesToHex(v, addSpaces = nil) s = "" v.each_byte{ |b| hex = b.to_s(16) hex = "0" + hex if hex.length == 1 s << hex s << " " if addSpaces == :add_spaces } s end |
.hexToBytes(v) ⇒ Object
Given a hex string representing a sequence of bytes, convert it the the original bytes. Inverse of bytesToHex.
31 32 33 |
# File 'lib/quartz_torrent/util.rb', line 31 def self.hexToBytes(v) [v].pack "H*" end |
.initThread(name) ⇒ Object
Method to set a few thread-local variables useful in debugging. Threads should call this when started.
95 96 97 |
# File 'lib/quartz_torrent/util.rb', line 95 def self.initThread(name) Thread.current[:name] = name end |
.logBacktraces(io = nil) ⇒ Object
Log backtraces of all threads currently running. The threads are logged to the passed io, or if that’s nil they are written to the logger named ‘util’ at error level.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/quartz_torrent/util.rb', line 74 def self.logBacktraces(io = nil) logger = nil logger = LogManager.getLogger("util") if ! io isLinux = RUBY_PLATFORM.downcase.include?("linux") Thread.list.each do |thread| lwpid = "" setThreadLwpid thread if ! thread[:lwpid] && isLinux lwpid = " [lwpid #{thread[:lwpid]}]" if thread[:lwpid] msg = "Thread #{thread[:name]} #{thread.object_id}#{lwpid}: #{thread.status}\n " + (thread.backtrace ? thread.backtrace.join("\n ") : "no backtrace") if io io.puts msg else logger.error msg end end end |
.setThreadLwpid(thread = nil) ⇒ Object
Store Linux Lightweight process ids (LWPID) on each thread. If this is called a while before logBacktraces the backtraces will include lwpids.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/quartz_torrent/util.rb', line 49 def self.setThreadLwpid(thread = nil) # This function works by calling the GETTID system call in Linux. That # system call must be called in the thread that we want to get the lwpid of, # but the user may not have created those threads and so can't call the system call # in those threads (think Sinatra). To get around this this function runs code in the # thread by adding a trace function to the thread, and on the first traced operation # stores the LWPID on the thread and unregisters itself. isLinux = RUBY_PLATFORM.downcase.include?("linux") return if !isLinux tracer = Proc.new do Thread.current[:lwpid] = syscall(SYSCALL_GETTID) if ! Thread.current[:lwpid] && isLinux Thread.current.set_trace_func(nil) end if thread thread.set_trace_func(tracer) else Thread.list.each { |thread| thread.set_trace_func(tracer) } end end |