Interview Question: Design a low level RSS feed

Shahar Shokrani
2 min readFeb 21, 2021

--

Really Simple Syndication or RSS is a web feed, that allow users to be notified when a website is update a specific topic.

For example: for a news website, like (https://www.ynet.co.il/), Jenny would like to be notified when there is a travel update or a politics update. Yossi would like to be notified when there is a politics update or a sport update.

So the RSS feeder should manage a Topics list, each Topic should manage its Subscribers, and each Subscriber should handle its own notification handle.

UML for RSS feed

RSS broker is responsible for holding a reference for all the topics (as a hashmap for O(1) accessing and avoid duplicates):

public class RSSBroker
{
private IDictionary<string, TopicObservable> _topics;
public RSSBroker()
{
this._topics = new Dictionary<string, TopicObservable>();
}
public void AddTopic(TopicObservable topic)
{
this._topics.TryAdd(topic.Id, topic);
}
public void UnsubscribeFromTopic(string id, UserObserver observer)
{
if (this._topics.ContainsKey(id))
this._topics[id].Unsubscribe(observer);
}
public void RegisterToTopic(string id, UserObserver observer)
{
if (this._topics.ContainsKey(id))
this._topics[id].Register(observer);
}
}

The Topic Observable is responsible for managing the clients observers, and send them a notify them when needed:

public class TopicObservable
{
private Dictionary<Guid, UserObserver> _observers = new Dictionary<Guid, UserObserver>();
public string Id { get; internal set; }
public TopicObservable(string id)
{
this.Id = id;
}
public void Register(UserObserver observer)
{
this._observers.TryAdd(observer.Id, observer);
}

public void Send(string message)
{
foreach (var observer in this._observers)
{
observer.Value.HandleNotification(this.Id, message);
}
}
public void Unsubscribe(UserObserver observer)
{
if (this._observers.ContainsKey(observer.Id))
this._observers.Remove(observer.Id);
}
}

The user observer:

public class UserObserver
{
public string Name { get; internal set; }
public Guid Id { get; internal set; }
public UserObserver(string name)
{
this.Id = Guid.NewGuid();
this.Name = name;
}
public void HandleNotification(string topicId, string message)
{
Console.WriteLine($"Hello {this.Name}! you have a new RSS event from {topicId}");
Console.WriteLine($"Message: {message}");
}
}

The Usage:

RSSBroker broker = new RSSBroker();TopicObservable politics = new TopicObservable("Politics");
TopicObservable travel = new TopicObservable("Travel");
TopicObservable tech = new TopicObservable("Tech");
broker.AddTopic(politics);
broker.AddTopic(travel);
broker.AddTopic(tech);
var jenny = new UserObserver("Jenny");
var yossi = new UserObserver("Yossi");
broker.RegisterToTopic("Politics", jenny);
broker.RegisterToTopic("Travel", jenny);
broker.RegisterToTopic("Politics", yossi);
broker.RegisterToTopic("Tech", yossi);
politics.Send("Palestinian elections are attempt to settle political landscape");
travel.Send("Israel is surprising location for digital nomads");
tech.Send("Israel says developing new Arrow- 4 ballistic missile shield with U.S.");

Will Output:

Hello Jenny! you have a new RSS event from Politics
Message: Palestinian elections are attempt to settle political landscape
Hello Yossi! you have a new RSS event from Politics
Message: Palestinian elections are attempt to settle political landscape
Hello Jenny! you have a new RSS event from Travel
Message: Israel is surprising location for digital nomads
Hello Yossi! you have a new RSS event from Tech
Message: Israel says developing new Arrow- 4 ballistic missile shield with U.S.

--

--