diff --git a/source/app.d b/source/app.d index d44fad8..594dc08 100644 --- a/source/app.d +++ b/source/app.d @@ -77,8 +77,11 @@ (RSSFeed[] fl) { fl.each!( (RSSFeed feed) { + logWarn("Starting: "~feed.name); // start workers to serve RSS data - tasks[feed.name] = runTask(&feedActor, feed.name, feed.path); + tasks[feed.name] = + runWorkerTaskH(&feedActor, feed.name, + feed.path, 0); }); }); diff --git a/source/cartastraccia/actor.d b/source/cartastraccia/actor.d index 7365655..40e3f39 100644 --- a/source/cartastraccia/actor.d +++ b/source/cartastraccia/actor.d @@ -22,35 +22,49 @@ alias TaskMap = Task[string]; +immutable uint MAX_RETRIES = 3; + /** * Actor in charge of: * - parsing a RSS feed * - dumping news to DB * - listening for messages from the webserver */ -void feedActor(immutable string feedName, immutable string path) @trusted +void feedActor(immutable string feedName, immutable string path, immutable uint retries) @trusted { RSS rss; URL url = URL(path); - requestHTTP(url, - (scope HTTPClientRequest req) { - req.method = HTTPMethod.GET; - }, - (scope HTTPClientResponse res) { - parseRSS(rss, res.bodyReader.readAllUTF8()); - }); + try { + requestHTTP(url, + (scope HTTPClientRequest req) { + req.method = HTTPMethod.GET; + }, + (scope HTTPClientResponse res) { + parseRSS(rss, res.bodyReader.readAllUTF8()); + }); + + } catch (Exception e) { + + logWarn("Failed connecting to: " ~ path ~ " with error: " ~ e.msg); + if(retries < MAX_RETRIES) { + logWarn("Retrying."); + feedActor(feedName, path, retries+1); + } + return; + + } rss.match!( (ref InvalidRSS i) { logWarn("Invalid feed at: "~path); logWarn("Caused by entry \""~i.element~"\": "~i.content); - busyListen(feedName, rss); + listenOnce(feedName, rss); }, (ref ValidRSS vr) { immutable fileName = "public/channels/"~feedName~".html"; createHTMLPage(vr, feedName, fileName); - busyListen(feedName, rss); + listenOnce(feedName, rss); }); } @@ -71,14 +85,17 @@ /** * Listen for messages from the webserver */ -void busyListen(immutable string feedName, ref RSS rss) { +void listenOnce(immutable string feedName, ref RSS rss) { + + bool quit = false; + rss.match!( (ref InvalidRSS i) { auto webTask = receiveOnly!Task; webTask.send(FeedActorResponse.INVALID); + quit = true; }, (ref ValidRSS vr) { - while(true) { try { // receive the webserver task @@ -90,6 +107,7 @@ return; } + // receive the actual request receive( (FeedActorRequest r) { @@ -107,7 +125,8 @@ case FeedActorRequest.QUIT: logInfo("Task exiting due to QUIT request."); - return; + quit = true; + break; default: logFatal("Task received unknown request."); @@ -121,8 +140,11 @@ } catch (Exception e) { logWarn("Waiting for actors to complete loading feeds."); } - } + }); + + if(quit) return; + else listenOnce(feedName, rss); } void dispatchCLI(scope Task task, immutable string data) diff --git a/source/cartastraccia/config.d b/source/cartastraccia/config.d index e84ad3f..9527570 100644 --- a/source/cartastraccia/config.d +++ b/source/cartastraccia/config.d @@ -39,6 +39,7 @@ alias RSSFeedList = SumType!(RSSFeed[], InvalidFeeds); + struct InvalidFeeds { string msg; diff --git a/source/cartastraccia/endpoint.d b/source/cartastraccia/endpoint.d index 196d428..0617ce6 100644 --- a/source/cartastraccia/endpoint.d +++ b/source/cartastraccia/endpoint.d @@ -62,7 +62,7 @@ lastUpdate[feed.name] = cast(DateTime)Clock.currTime(); tasks[feed.name].send(FeedActorRequest.QUIT); - tasks[feed.name] = runTask(&feedActor, feed.name, feed.path); + tasks[feed.name] = runWorkerTaskH(&feedActor, feed.name, feed.path, 0); logWarn("Finished updating: " ~ feed.name);