Coder Social home page Coder Social logo

timewheel's Introduction

timewheel

精度可选的时间轮算法,用GoLang实现。

Example

一般用法。

import (
    "github.com/joyant/timewheel"
    "fmt"
    "time"
)

func main () {
    globalHandler := func(key string, data interface{}) error {
        panic(fmt.Sprintf("key %s data %v panic", key, data))
    }
    errHandler := func(err error) {
        fmt.Println(err)
    }
    tw := timewheel.NewTimeWheel(timewheel.PrecisionSecond, globalHandler, errHandler)
    if tw != nil {
        task1 := timewheel.NewTask("task1", "task1's data", time.Now().Add(time.Second * 3), nil)
        tw.add(task1)
    }
    quit := make(chan struct{})
    <-quit
}

每个任务都可以有自己的任务处理函数,任务自己的处理函数比绑定在timewheel上的任务处理函数优先级高。

import (
    "github.com/joyant/timewheel"
    "fmt"
    "time"
)

func main () {
    globalHandler := func(key string, data interface{}) error {
        panic(fmt.Sprintf("key %s data %v panic", key, data)) // 不会被执行
    }
    errHandler := func(err error) {
        fmt.Println(err) // 因为任务执行时并不会`panic`,所以不会被执行
    }
    task1Handler = func(key string, data interface{}) error {
        fmt.Printf("key %s data %v finished \n", key, data) // 会被执行
        return nil
    }
    tw := timewheel.NewTimeWheel(timewheel.PrecisionSecond, globalHandler, errHandler)
    if tw != nil {
        task1 := timewheel.NewTask("task1", "task1's data", time.Now().Add(time.Second * 3), task1Handler)
        tw.add(task1)
    }
    quit := make(chan struct{})
    <-quit
}

上面的例子精度都是秒,如果对精度要求比较高,可以用毫秒,只有这两种精度选择。

import (
    "github.com/joyant/timewheel"
    "fmt"
    "time"
)

func main () {
    task1Handler = func(key string, data interface{}) error {
        fmt.Printf("key %s data %v finished \n", key, data)
        return nil
    }
    tw := timewheel.NewTimeWheel(timewheel.PrecisionMillisecond, globalHandler, nil)
    if tw != nil {
        //任务将在3毫秒后执行
        task1 := timewheel.NewTask("task1", "task1's data", time.Now().Add(time.Millisecond * 3), task1Handler)
        tw.add(task1)
    }
    quit := make(chan struct{})
    <-quit
}

默认的,任务的执行是串行的(阻塞模式),并没有跑在独立的协程中,如果任务执行比较耗时,需要作如下设置:

import (
    "github.com/joyant/timewheel"
    "fmt"
    "time"
)

func main () {
    timewheel.Nonblock = true // 这意味着每个任务执行都会新起一个协程

    task1Handler = func(key string, data interface{}) error {
        fmt.Printf("key %s data %v finished \n", key, data)
        return nil
    }
    tw := timewheel.NewTimeWheel(timewheel.PrecisionMillisecond, globalHandler, nil)
    if tw != nil {
        //任务将在3毫秒后执行
        task1 := timewheel.NewTask("task1", "task1's data", time.Now().Add(time.Millisecond * 3), task1Handler)
        tw.add(task1)
    }
    quit := make(chan struct{})
    <-quit
}

需要注意的是,做了timewheel.Nonblock = true设置后,timewheel并没有对协程的数量做限制,所以在任务较多的情况下,协程会无限制 增加,这并不是一个好的实践,如果任务较多,调用者不应该设置timewheel.Nonblock = true,而是应该把任务放在队列里,并且在接收任务的 时候要尽可能的快,比如这样:

import (
    "github.com/joyant/timewheel"
    "fmt"
    "time"
)

type MyTask struct {
    key string
    data interface{}
}

func main () {
    queue := make(chan MyTask, 1E4)
    task1Handler = func(key string, data interface{}) error {
        queue <- MyTask{ // 不要阻塞,要尽快的放入队列,不要在这里执行耗时任务,否则之后的任务会延迟
            key: key,
            data: data,
        }
        return nil
    }
    tw := timewheel.NewTimeWheel(timewheel.PrecisionMillisecond, globalHandler, nil)
    if tw != nil {
        task1 := timewheel.NewTask("task1", "task1's data", time.Now().Add(time.Millisecond * 3), task1Handler)
        tw.add(task1)
    }
    for _, q := range queue {
        fmt.Println(q.key, q.data)
    }
}

也可以删除任务和停止任务。

tw.DelTask("task1")
tw.Stop()

timewheel's People

Contributors

joyant 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.