func (d *Dcron) AddJob(jobName, cronStr string, job Job) (err error) {
	return d.addJob(jobName, cronStr, nil, job)
}
AddJob  add a job
package dcron
import (
	"errors"
	. "github.com/libi/dcron/driver"
	"github.com/robfig/cron/v3"
	"log"
	"os"
	"sync"
	"time"
)
const defaultReplicas = 50
const defaultDuration = time.Second
type Dcron struct {
	jobs       map[string]*JobWarpper
	mu         sync.RWMutex
	ServerName string
	nodePool   *NodePool
	isRun      bool
	logger interface{ Printf(string, ...interface{}) }
	nodeUpdateDuration time.Duration
	hashReplicas       int
	cr        *cron.Cron
	crOptions []cron.Option
}
func NewDcron(serverName string, driver Driver, cronOpts ...cron.Option) *Dcron {
	dcron := newDcron(serverName)
	dcron.crOptions = cronOpts
	dcron.cr = cron.New(cronOpts...)
	dcron.nodePool = newNodePool(serverName, driver, dcron, dcron.nodeUpdateDuration, dcron.hashReplicas)
	return dcron
}
func NewDcronWithOption(serverName string, driver Driver, dcronOpts ...Option) *Dcron {
	dcron := newDcron(serverName)
	for _, opt := range dcronOpts {
		opt(dcron)
	}
	dcron.cr = cron.New(dcron.crOptions...)
	dcron.nodePool = newNodePool(serverName, driver, dcron, dcron.nodeUpdateDuration, dcron.hashReplicas)
	return dcron
}
func newDcron(serverName string) *Dcron {
	return &Dcron{
		ServerName:         serverName,
		logger:             log.New(os.Stdout, "[dcron] ", log.LstdFlags),
		jobs:               make(map[string]*JobWarpper),
		crOptions:          make([]cron.Option, 0),
		nodeUpdateDuration: defaultDuration,
		hashReplicas:       defaultReplicas,
	}
}
func (d *Dcron) SetLogger(logger *log.Logger) {
	d.logger = logger
}
func (d *Dcron) GetLogger() interface{ Printf(string, ...interface{}) } {
	return d.logger
}
func (d *Dcron) info(format string, v ...interface{}) {
	d.logger.Printf("INFO: "+format, v...)
}
func (d *Dcron) err(format string, v ...interface{}) {
	d.logger.Printf("ERR: "+format, v...)
}