mirror of https://github.com/aria2/aria2
Added a new DownloadEvent for the demand of to know segment downloaded.
The new `DownloadEvent` name is `EVENT_ON_SEGMENT_COMPLETE`, which would indicate a segment has completed. To inform this information, a new struct named `SegmentInfo` was added in `<aria2/aria2.h>`. This parameter is then added to the `DownloadEventCallback`.pull/1223/head
parent
475e6c5997
commit
b6b6cc3f95
|
@ -34,6 +34,7 @@
|
||||||
/* copyright --> */
|
/* copyright --> */
|
||||||
#include "ApiCallbackDownloadEventListener.h"
|
#include "ApiCallbackDownloadEventListener.h"
|
||||||
#include "RequestGroup.h"
|
#include "RequestGroup.h"
|
||||||
|
#include "Segment.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -46,9 +47,16 @@ ApiCallbackDownloadEventListener::ApiCallbackDownloadEventListener(
|
||||||
ApiCallbackDownloadEventListener::~ApiCallbackDownloadEventListener() = default;
|
ApiCallbackDownloadEventListener::~ApiCallbackDownloadEventListener() = default;
|
||||||
|
|
||||||
void ApiCallbackDownloadEventListener::onEvent(DownloadEvent event,
|
void ApiCallbackDownloadEventListener::onEvent(DownloadEvent event,
|
||||||
const RequestGroup* group)
|
const RequestGroup* group,
|
||||||
|
const Segment* segment)
|
||||||
{
|
{
|
||||||
callback_(session_, event, group->getGID(), userData_);
|
struct SegmentInfo info;
|
||||||
|
if (segment) {
|
||||||
|
info.index = segment->getIndex();
|
||||||
|
info.position = segment->getPosition();
|
||||||
|
info.length = segment->getLength();
|
||||||
|
}
|
||||||
|
callback_(session_, event, group->getGID(), userData_, &info);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -46,7 +46,8 @@ public:
|
||||||
void* userData);
|
void* userData);
|
||||||
virtual ~ApiCallbackDownloadEventListener();
|
virtual ~ApiCallbackDownloadEventListener();
|
||||||
virtual void onEvent(DownloadEvent event,
|
virtual void onEvent(DownloadEvent event,
|
||||||
const RequestGroup* group) CXX11_OVERRIDE;
|
const RequestGroup* group,
|
||||||
|
const Segment* segment = nullptr) CXX11_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Session* session_;
|
Session* session_;
|
||||||
|
|
|
@ -320,4 +320,9 @@ void DownloadContext::updateUploadLength(size_t bytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DownloadContext::completedSegment(const std::shared_ptr<Segment>& segment) const
|
||||||
|
{
|
||||||
|
ownerRequestGroup_->completedSegment(segment);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -54,6 +54,7 @@ namespace aria2 {
|
||||||
class RequestGroup;
|
class RequestGroup;
|
||||||
class Signature;
|
class Signature;
|
||||||
class FileEntry;
|
class FileEntry;
|
||||||
|
class Segment;
|
||||||
|
|
||||||
class DownloadContext {
|
class DownloadContext {
|
||||||
private:
|
private:
|
||||||
|
@ -233,6 +234,10 @@ public:
|
||||||
// RequestGroupMan via getOwnerRequestGroup().
|
// RequestGroupMan via getOwnerRequestGroup().
|
||||||
void updateUploadLength(size_t bytes);
|
void updateUploadLength(size_t bytes);
|
||||||
void updateUploadSpeed(size_t bytes);
|
void updateUploadSpeed(size_t bytes);
|
||||||
|
|
||||||
|
// This method will be called by corresponding SegmentMan
|
||||||
|
// if a Segment get downloaded
|
||||||
|
void completedSegment(const std::shared_ptr<Segment>& segment) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -48,10 +48,11 @@ void Notifier::addDownloadEventListener(DownloadEventListener* listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
void Notifier::notifyDownloadEvent(DownloadEvent event,
|
void Notifier::notifyDownloadEvent(DownloadEvent event,
|
||||||
const RequestGroup* group)
|
const RequestGroup* group,
|
||||||
|
const Segment* segment)
|
||||||
{
|
{
|
||||||
for (auto listener : listeners_) {
|
for (auto listener : listeners_) {
|
||||||
listener->onEvent(event, group);
|
listener->onEvent(event, group, segment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,25 +45,38 @@
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
class RequestGroup;
|
class RequestGroup;
|
||||||
|
class Segment;
|
||||||
|
|
||||||
struct DownloadEventListener {
|
struct DownloadEventListener {
|
||||||
virtual ~DownloadEventListener() = default;
|
virtual ~DownloadEventListener() = default;
|
||||||
virtual void onEvent(DownloadEvent event, const RequestGroup* group) = 0;
|
virtual void onEvent(DownloadEvent event,
|
||||||
|
const RequestGroup* group,
|
||||||
|
const Segment* segment = nullptr) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Notifier {
|
class Notifier {
|
||||||
public:
|
public:
|
||||||
Notifier();
|
Notifier();
|
||||||
~Notifier();
|
~Notifier();
|
||||||
|
|
||||||
void addDownloadEventListener(DownloadEventListener* listener);
|
void addDownloadEventListener(DownloadEventListener* listener);
|
||||||
// Notifies the download event to all listeners.
|
// Notifies the download event to all listeners.
|
||||||
void notifyDownloadEvent(DownloadEvent event, const RequestGroup* group);
|
void notifyDownloadEvent(DownloadEvent event,
|
||||||
|
const RequestGroup* group,
|
||||||
|
const Segment* segment=nullptr);
|
||||||
|
|
||||||
void notifyDownloadEvent(DownloadEvent event,
|
void notifyDownloadEvent(DownloadEvent event,
|
||||||
const std::shared_ptr<RequestGroup>& group)
|
const std::shared_ptr<RequestGroup>& group)
|
||||||
{
|
{
|
||||||
notifyDownloadEvent(event, group.get());
|
notifyDownloadEvent(event, group.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void notifyDownloadSegmentEvent(DownloadEvent event,
|
||||||
|
const std::shared_ptr<RequestGroup>& group,
|
||||||
|
const std::shared_ptr<Segment>& segment)
|
||||||
|
{
|
||||||
|
notifyDownloadEvent(event, group.get(), segment.get());
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<DownloadEventListener*> listeners_;
|
std::vector<DownloadEventListener*> listeners_;
|
||||||
|
|
|
@ -881,6 +881,11 @@ void RequestGroup::createNextCommand(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RequestGroup::completedSegment(const std::shared_ptr<Segment>& segment) const
|
||||||
|
{
|
||||||
|
requestGroupMan_->completedSegment(requestGroupMan_->findGroup(this->gid_->getNumericId()), segment);
|
||||||
|
}
|
||||||
|
|
||||||
std::string RequestGroup::getFirstFilePath() const
|
std::string RequestGroup::getFirstFilePath() const
|
||||||
{
|
{
|
||||||
assert(downloadContext_);
|
assert(downloadContext_);
|
||||||
|
|
|
@ -70,6 +70,7 @@ struct DownloadResult;
|
||||||
class URISelector;
|
class URISelector;
|
||||||
class URIResult;
|
class URIResult;
|
||||||
class RequestGroupMan;
|
class RequestGroupMan;
|
||||||
|
class Segment;
|
||||||
#ifdef ENABLE_BITTORRENT
|
#ifdef ENABLE_BITTORRENT
|
||||||
class BtRuntime;
|
class BtRuntime;
|
||||||
class PeerStorage;
|
class PeerStorage;
|
||||||
|
@ -240,6 +241,10 @@ public:
|
||||||
|
|
||||||
void createNextCommand(std::vector<std::unique_ptr<Command>>& commands,
|
void createNextCommand(std::vector<std::unique_ptr<Command>>& commands,
|
||||||
DownloadEngine* e);
|
DownloadEngine* e);
|
||||||
|
|
||||||
|
// This method will be called by corresponding DownloadContext
|
||||||
|
// if a Segment get downloaded
|
||||||
|
void completedSegment(const std::shared_ptr<Segment>& segment) const;
|
||||||
|
|
||||||
bool downloadFinished() const;
|
bool downloadFinished() const;
|
||||||
|
|
||||||
|
|
|
@ -248,6 +248,16 @@ void notifyDownloadEvent(DownloadEvent event,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void notifyDownloadSegmentEvent(DownloadEvent event,
|
||||||
|
const std::shared_ptr<RequestGroup>& group,
|
||||||
|
const std::shared_ptr<Segment>& segment)
|
||||||
|
{
|
||||||
|
// Check NULL to make unit test easier.
|
||||||
|
if (SingletonHolder<Notifier>::instance()) {
|
||||||
|
SingletonHolder<Notifier>::instance()->notifyDownloadSegmentEvent(event, group, segment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -1112,4 +1122,11 @@ int RequestGroupMan::optimizeConcurrentDownloads()
|
||||||
|
|
||||||
return maxConcurrentDownloads;
|
return maxConcurrentDownloads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RequestGroupMan::completedSegment(const std::shared_ptr<RequestGroup>& group,
|
||||||
|
const std::shared_ptr<Segment>& segment) const
|
||||||
|
{
|
||||||
|
notifyDownloadSegmentEvent(EVENT_ON_SEGMENT_COMPLETE, group, segment);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -61,6 +61,7 @@ class OutputFile;
|
||||||
class UriListParser;
|
class UriListParser;
|
||||||
class WrDiskCache;
|
class WrDiskCache;
|
||||||
class OpenedFileCounter;
|
class OpenedFileCounter;
|
||||||
|
class Segment;
|
||||||
|
|
||||||
typedef IndexedList<a2_gid_t, std::shared_ptr<RequestGroup>> RequestGroupList;
|
typedef IndexedList<a2_gid_t, std::shared_ptr<RequestGroup>> RequestGroupList;
|
||||||
typedef IndexedList<a2_gid_t, std::shared_ptr<DownloadResult>>
|
typedef IndexedList<a2_gid_t, std::shared_ptr<DownloadResult>>
|
||||||
|
@ -213,6 +214,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool setupOptimizeConcurrentDownloads();
|
bool setupOptimizeConcurrentDownloads();
|
||||||
|
|
||||||
|
// This method will be called by corresponding RequestGroup
|
||||||
|
// if a segment get downloaded
|
||||||
|
void completedSegment(const std::shared_ptr<RequestGroup>& group,
|
||||||
|
const std::shared_ptr<Segment>& segment) const;
|
||||||
|
|
||||||
void showDownloadResults(OutputFile& o, bool full) const;
|
void showDownloadResults(OutputFile& o, bool full) const;
|
||||||
|
|
||||||
|
|
|
@ -376,6 +376,7 @@ bool SegmentMan::completeSegment(cuid_t cuid,
|
||||||
pieceStorage_->completePiece(segment->getPiece());
|
pieceStorage_->completePiece(segment->getPiece());
|
||||||
pieceStorage_->advertisePiece(cuid, segment->getPiece()->getIndex(),
|
pieceStorage_->advertisePiece(cuid, segment->getPiece()->getIndex(),
|
||||||
global::wallclock());
|
global::wallclock());
|
||||||
|
downloadContext_->completedSegment(segment);
|
||||||
auto itr = std::find_if(usedSegmentEntries_.begin(),
|
auto itr = std::find_if(usedSegmentEntries_.begin(),
|
||||||
usedSegmentEntries_.end(), FindSegmentEntry(segment));
|
usedSegmentEntries_.end(), FindSegmentEntry(segment));
|
||||||
if (itr == usedSegmentEntries_.end()) {
|
if (itr == usedSegmentEntries_.end()) {
|
||||||
|
|
|
@ -66,7 +66,8 @@ void WebSocketSessionMan::removeSession(
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebSocketSessionMan::addNotification(const std::string& method,
|
void WebSocketSessionMan::addNotification(const std::string& method,
|
||||||
const RequestGroup* group)
|
const RequestGroup* group,
|
||||||
|
const Segment* segment)
|
||||||
{
|
{
|
||||||
auto dict = Dict::g();
|
auto dict = Dict::g();
|
||||||
dict->put("jsonrpc", "2.0");
|
dict->put("jsonrpc", "2.0");
|
||||||
|
@ -89,6 +90,7 @@ const std::string ON_DOWNLOAD_START = "aria2.onDownloadStart";
|
||||||
const std::string ON_DOWNLOAD_PAUSE = "aria2.onDownloadPause";
|
const std::string ON_DOWNLOAD_PAUSE = "aria2.onDownloadPause";
|
||||||
const std::string ON_DOWNLOAD_STOP = "aria2.onDownloadStop";
|
const std::string ON_DOWNLOAD_STOP = "aria2.onDownloadStop";
|
||||||
const std::string ON_DOWNLOAD_COMPLETE = "aria2.onDownloadComplete";
|
const std::string ON_DOWNLOAD_COMPLETE = "aria2.onDownloadComplete";
|
||||||
|
const std::string ON_SEGMENT_COMPLETE = "aria2.onSegmentComplete";
|
||||||
const std::string ON_DOWNLOAD_ERROR = "aria2.onDownloadError";
|
const std::string ON_DOWNLOAD_ERROR = "aria2.onDownloadError";
|
||||||
const std::string ON_BT_DOWNLOAD_COMPLETE = "aria2.onBtDownloadComplete";
|
const std::string ON_BT_DOWNLOAD_COMPLETE = "aria2.onBtDownloadComplete";
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -105,6 +107,8 @@ const std::string& getMethodName(DownloadEvent event)
|
||||||
return ON_DOWNLOAD_STOP;
|
return ON_DOWNLOAD_STOP;
|
||||||
case EVENT_ON_DOWNLOAD_COMPLETE:
|
case EVENT_ON_DOWNLOAD_COMPLETE:
|
||||||
return ON_DOWNLOAD_COMPLETE;
|
return ON_DOWNLOAD_COMPLETE;
|
||||||
|
case EVENT_ON_SEGMENT_COMPLETE:
|
||||||
|
return ON_SEGMENT_COMPLETE;
|
||||||
case EVENT_ON_DOWNLOAD_ERROR:
|
case EVENT_ON_DOWNLOAD_ERROR:
|
||||||
return ON_DOWNLOAD_ERROR;
|
return ON_DOWNLOAD_ERROR;
|
||||||
case EVENT_ON_BT_DOWNLOAD_COMPLETE:
|
case EVENT_ON_BT_DOWNLOAD_COMPLETE:
|
||||||
|
@ -119,9 +123,10 @@ const std::string& getMethodName(DownloadEvent event)
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void WebSocketSessionMan::onEvent(DownloadEvent event,
|
void WebSocketSessionMan::onEvent(DownloadEvent event,
|
||||||
const RequestGroup* group)
|
const RequestGroup* group,
|
||||||
|
const Segment* segment)
|
||||||
{
|
{
|
||||||
addNotification(getMethodName(event), group);
|
addNotification(getMethodName(event), group, segment);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace rpc
|
} // namespace rpc
|
||||||
|
|
|
@ -59,9 +59,12 @@ public:
|
||||||
~WebSocketSessionMan();
|
~WebSocketSessionMan();
|
||||||
void addSession(const std::shared_ptr<WebSocketSession>& wsSession);
|
void addSession(const std::shared_ptr<WebSocketSession>& wsSession);
|
||||||
void removeSession(const std::shared_ptr<WebSocketSession>& wsSession);
|
void removeSession(const std::shared_ptr<WebSocketSession>& wsSession);
|
||||||
void addNotification(const std::string& method, const RequestGroup* group);
|
void addNotification(const std::string& method,
|
||||||
|
const RequestGroup* group,
|
||||||
|
const Segment* segment = nullptr);
|
||||||
virtual void onEvent(DownloadEvent event,
|
virtual void onEvent(DownloadEvent event,
|
||||||
const RequestGroup* group) CXX11_OVERRIDE;
|
const RequestGroup* group,
|
||||||
|
const Segment* segment = nullptr) CXX11_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WebSocketSessions sessions_;
|
WebSocketSessions sessions_;
|
||||||
|
|
|
@ -119,6 +119,10 @@ enum DownloadEvent {
|
||||||
* Indicating download has completed.
|
* Indicating download has completed.
|
||||||
*/
|
*/
|
||||||
EVENT_ON_DOWNLOAD_COMPLETE,
|
EVENT_ON_DOWNLOAD_COMPLETE,
|
||||||
|
/**
|
||||||
|
* Indicating a segment has completed.
|
||||||
|
*/
|
||||||
|
EVENT_ON_SEGMENT_COMPLETE,
|
||||||
/**
|
/**
|
||||||
* Indicating download has stopped because of the error.
|
* Indicating download has stopped because of the error.
|
||||||
*/
|
*/
|
||||||
|
@ -130,6 +134,33 @@ enum DownloadEvent {
|
||||||
EVENT_ON_BT_DOWNLOAD_COMPLETE
|
EVENT_ON_BT_DOWNLOAD_COMPLETE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct
|
||||||
|
*
|
||||||
|
* The segment information.
|
||||||
|
*/
|
||||||
|
struct SegmentInfo {
|
||||||
|
/**
|
||||||
|
* The constructor fills default values for all members.
|
||||||
|
*/
|
||||||
|
SegmentInfo();
|
||||||
|
/**
|
||||||
|
* The index of a piece.
|
||||||
|
* The default value is ``0``.
|
||||||
|
*/
|
||||||
|
size_t index;
|
||||||
|
/**
|
||||||
|
* Specify the beginning offset of file.
|
||||||
|
* The default value is ``0``.
|
||||||
|
*/
|
||||||
|
int64_t position;
|
||||||
|
/**
|
||||||
|
* Specify number of bytes containing in the segment.
|
||||||
|
* The default value is ``0``.
|
||||||
|
*/
|
||||||
|
int64_t length;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @functypedef
|
* @functypedef
|
||||||
*
|
*
|
||||||
|
@ -138,12 +169,15 @@ enum DownloadEvent {
|
||||||
* |gid| refers to the download which this event was fired on. The
|
* |gid| refers to the download which this event was fired on. The
|
||||||
* |userData| is a pointer specified in
|
* |userData| is a pointer specified in
|
||||||
* :member:`SessionConfig::userData`.
|
* :member:`SessionConfig::userData`.
|
||||||
|
* |segmentInfo| will be non-default values if the event
|
||||||
|
* is `aria2::EVENT_ON_SEGMENT_COMPLETE`.
|
||||||
*
|
*
|
||||||
* At the moment, the return value is ignored, but the implementation
|
* At the moment, the return value is ignored, but the implementation
|
||||||
* of this callback should return 0 for compatibility.
|
* of this callback should return 0 for compatibility.
|
||||||
*/
|
*/
|
||||||
typedef int (*DownloadEventCallback)(Session* session, DownloadEvent event,
|
typedef int (*DownloadEventCallback)(Session* session, DownloadEvent event,
|
||||||
A2Gid gid, void* userData);
|
A2Gid gid, void* userData,
|
||||||
|
SegmentInfo* segmentInfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct
|
* @struct
|
||||||
|
|
Loading…
Reference in New Issue