Coder Social home page Coder Social logo

efuture's Introduction

eFuture

Build Status GitHub

Send an Email to future!

It is a really amazing thing that some day you received a Email from past, isn't it?

Design

The key point of this project is to store future-emails and send them at a specified time point. So we need users to input or select:

  1. The Email address to receive the future-email
  2. The subject of future-email
  3. The date this future-email been deliveried
  4. The content of this future-email

After user fill in the four part above properly, we now need a reliably component to reserve these Emails and to send them at a specified time point. For this project, I choose redis to guarantee future-email being consumed only at specified time and being backuped for unexpected server fault.

I choose to implement this project through python. At first I'd like to use golang, but using golang to write web application is such an uncomfortable thing, so I finally choose to use python.

RabbitMQ

We need rabbitmq to support delayed tasks. Using rabbitmq to provide delayed task we need a feature of queue: x-dead-letter-exchange. Declare a x-dead-letter-exchange property for a queue, the queue will automatically forward expired messages to the specified exchange. What we need to do is to receive messages for a queue which is bind to the exchange too.

Redis

After trying to use RabbitMQ to implement delayed tasks I found that rabbitmq is not a good idea. The implement has a fatal flaw that in the dead queue, if the top task is not expired, although the following one or more tasks is expired, they won't be forwarded the specified exchange. This causes the shorter task waiting for the longer task and the shorter task cannot be consumed at time.

So I choose redis to implement the delayed task. ZSet is a PriorityQueue-Like data structure which can automatically sort tasks by a score. We can attach a timestamp to task when putting them into redis. By doing so, the top task in zset is the one bind to the smallest timestamp and also is the first task that should be done. And in our code, we check the first task in zset every second, compare its score with time.Now's timestamp. If the score is bigger than time.Now's timestamp, this means that it is time to consume the top task.

How to run?

In order to run this project, you need to edit your own config files first, here is a template:

{
  "username": "[email protected]",
  "password": "password",
  "smtp": "smtp.example.com",
  "smtp_port": "587",
  "redis_host": "127.0.0.1",
  "redis_port": "6379",
  "redis_password": "",
  "redis_db": 0,
  "log_path": "/tmp/eFuture.log",
  "log_level": "DEBUG"
}

username, password, smtp and smtp_port is required, because of eFuture need them to send Emails. If you use docker to run this project, make sure to change the value of redis_host to redis if you use link to link this container to a exist redis container.

In this project I have declared two ways to read configurations.

  1. Environment variable EFUTURE_CONFIG
  2. Config file /data/eFuture/config.json

The code will first try to read ${EFUTURE_CONFIG} and if fails it will try to read /data/eFuture/config.json. So make sure you have the above two ways at least one available.

For example, if you'd like to declare a environment variable and the file path is /home/xxx/eFuture/config.json. You need to declare that:

export EFUTURE_CONFIG=/home/xxx/eFuture/config.json

Also, this project use Redis to provide delayed task queue, so redis is required.

After configuring config file and redis properly, run the project:

python main.py

Run in Docker

A docker version project is provided also.

$ docker pull xlui/efuture
$ docker run --name redis -p 127.0.0.1:6379:6379 -d redis
$ docker run --name efuture --link redis
-p 127.0.0.1:8080:5000
-v /path/to/config.json:/data/eFuture/config.json
-d xlui/efuture

LICENSE

MIT

efuture's People

Contributors

xlui avatar dependabot[bot] avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.