Skip to content

bgunson/as

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AdShare

CPSC 559 - Introduction to Distributed Systems

Final Project - University of Calgary (Winter 2023)

Tests

Peer Workflow

Proxy deploy and publish

Built using

node.js react express.js socket.io google cloud docker


Table of Contents
  1. Inspiration
  2. Getting Started
  3. How does it work
  4. Distributed System Features
  5. Configuration
  6. Feedback
  7. Contributors

Inspiration 🌌

Web advertising is everywhere these days, from banner ads to pop-ups and even videos. But did you know that the industry is dominated by a few big players, like Google, Amazon and Ezoic, who control all the ad hosting from their massive data centers? For small businesses, it's an uphill battle to compete with these giants and turn a meaningful profit. Introducing AdShare!

Our platform is a solution for the challenges posed by the current centralized approach to web advertising. With the rise of Web3.0 and the push towards decentralization, we believe that our decentralized advertising platform aligns with the future of the web. Anyone can use some spare computing power to host ads and earn money, making it easier and more affordable for smaller players to get their message out there. Plus, by cutting out the middleman, we're reducing the overhead costs for everyone involved. It's a win-win for advertisers and users alike!

(back to top ⬆️ )

Getting Started 🎉

  • Prerequisites

    • For the simplest way, ensure Docker and Docker Compose are installed locally.
    • For the long way, ensure Node and npm are installed locally.
  • Docker 🐳

    1. Using pre-built images 📷 (recommended)

      • Container images for both the Proxy and Peer are available on GHCR which can be pulled and used directly.

      • Peer:

        • Create a new local directory for storing ads.
        • Run docker run -v /path/to/local/ads:peer/ads -p 3000:3000/tcp bgunson/as-peer
        • Terminate at any time by pressing Ctrl+C.
        • NB: If you want to run multiple Peers simultaneously, make sure you run the commands on separate directories and change the ports.
      • Proxy:

        • In a terminal, run docker run -p 50000:50000/tcp bgunson/as-proxy
          • NB: This will start the container in foreground mode and your terminal will be attached to the container's process.
          • To avoid this, add a -d option after run so that the container will run in the background.
        • Terminate at any time by pressing Ctrl+C.
    2. Using Docker Compose 📚

      • To run the Peer as a Docker container:
        • Clone the project repository and cd to as/peer via terminal/console.
        • Run docker-compose up in the root directory.
        • Terminate at any time by pressing Ctrl+C.
  • Node and npm

    If you want to get things set up and running locally this way, you need to clone the project repository.

    • To run a Peer:

      • Open a terminal, cd into where you cloned the repo.
      • cd into as/peer folder.
      • Run npm install to install the project dependencies.
      • Run npm start to start the Peer server.
        • You can run any number of these in multiple terminals.
    • To setup the GUI for the Peer:

      • Open another terminal, cd into where you cloned the repo.
      • cd into as/peer/frontend folder.
      • Run npm run build
    • To run a Proxy:

      • Open another terminal, again cd into where you cloned the repo.
      • cd into as/proxy folder.
      • Run npm install followed by npm start

    Once a Peer is running and connected to a Proxy's swarm, you can access the GUI by visiting http://localhost:3000.

    Then finally, open the client by going cloning the repo locally and opening docs/index.html in your preferred web browser.

    You can also visit https://bengunson.me/as-example-client

    You should then see an iframed ad which was given by the to the client from the peer server(s) via the proxy.

    To learn more about changing the port to something else and for configuring stuff, read this section.

(back to top ⬆️ )

How does it work ❓

AdShare works by allowing users to download a client, called the Peer, that turns their computer into a peer server. Once this peer joins a Swarm network of other Peers, they can host and exchange ads with each other. We use Docker for improved scalability and portability, so our application can work seamlessly in different environments.

Users can upload their own ads and choose how much they want to pay to ensure their ad gets replicated and seen by more people. The more replication, the more money they can earn. Users running the peer server are paid according to how many ads they serve to clients, creating a supply and demand system in the marketplace.

A Proxy server is used to "broker" connections between clients and peer servers. If no peers are available, the proxy server will serve an advertisement for our service.

You can read our Proof of Concept here to get a better idea of what's going on under the hood!

(back to top ⬆️ )

Implemented Features for the Distributed System 🔆

You can read in-depth about our system architecture and communication model here.

Replication Users running the peer app on their machines can host ads for clients not originally assigned to them. To enable this, we've created a mechanism for replicating ads between peers. When a peer is empty, it simply sends a request to the proxy to replicate ads from other peers. The proxy then sends a request to all non-empty peers to send an ad, which is then replicated to the empty peer. The first peer request to reach the proxy is the first ad sent to the empty peer. Need more ads? Just send another replication request. And if there's a new ad in the system, send a replication request to the proxy to share it with other peers.
Additionally, replication serves the purpose of maintaining fault tolerance within the system. Once a new server joins the swarm, it is immediately replicated to ensure that the system remains stable and available to clients. The proxy server maintains a dynamic list of active peers in the swarm.
Scalability By leveraging the distributed nature of peer-to-peer networks, we can seamlessly scale the system as more users and ads are added, without the need for a central server or a single point of failure. To further simplify deployment and management, we use Docker containers to ensure consistency across different machines and environments. This also allows for easier scaling by allowing for the creation of new instances of the app on-demand!
Fault Tolerance The decentralized nature of our ad-swarm means that we can withstand the failure of up to n-1 peers. Here's how it works: when a request is sent out for an ad, all peers in the swarm respond. If one fails to respond, the proxy simply ignores it and serves the next response it receives. And don't worry if one of your peers does fail - simply reboot the application and rejoin the swarm!
Consistency With large amounts of ads and peers, storing every file on every machine becomes impractical. Our solution? A weak consistency mode! This ensures that all ad copies are dispersed throughout the swarm, so no peer misses out on the latest ads!
Synchronization Synchronization is passively implemented in the swarm as we are not interchanging time-dependent information and just static image files. Logical timestamps, based on Lamport algorithm, are incorporated in order to keep track of which ads are on each peer, and to be able to determine when each ad was placed (either through direct upload or replication) on each peer.
GUI Built with React, our GUI provides a streamlined way to manage ads directly from the peer. With intuitive features and a clean interface, managing ads is as easy as pie!

(back to top ⬆️ )

Configuration

You can tweak the Docker Compose file and tweak the values defined in environment.

It is recommended to use the --no-cache option when building images.

To make things even simpler, a .env file which contains the necessary configuration for the application to run, can be used.

This way, you can build a image by running: docker-compose --env-file ./path/to/.env build --no-cache --force-rm

You can create the .env file and place them in the peer folder (and the proxy folder as well if you want to run the Proxy locally!).

The general format of a .env file is:

VARIABLE1=YOUR_VALUE1
VARIABLE2=YOUR_VALUE2 

You can read more about the environment variables here.

(back to top ⬆️ )

What's next for AdShare 🎯

We would love some constructive feedback. This was a great learning experience for us all and we would love to see how we could improve the project.

(back to top ⬆️ )

Contributors 📜

  • Bennett Gunson
  • Kirill Larshin
  • Steven Susanto
  • Taylor Jones
  • Ranadip Chatterjee

(back to top ⬆️ )