예제 #1
0
func ExampleApp_local() {
	// this example demonstrates a job queue runs in background

	var err error
	defer func() {
		if err != nil {
			fmt.Printf("%v\n", err)
		}
	}()

	// a App in local mode
	app, err := dingo.NewApp("local", nil)
	if err != nil {
		return
	}

	// register a worker function murmur
	err = app.Register("murmur", func(msg string, repeat int, interval time.Duration) {
		for ; repeat > 0; repeat-- {
			select {
			case <-time.After(interval):
				fmt.Printf("%v\n", msg)
			}
		}
	})
	if err != nil {
		return
	}

	// allocate 5 workers, sharing 1 report channel
	_, err = app.Allocate("murmur", 5, 1)
	if err != nil {
		return
	}

	results := []*dingo.Result{}
	// invoke 10 tasks
	for i := 0; i < 10; i++ {
		results = append(
			results,
			dingo.NewResult(
				// name, option, parameter#1, parameter#2, parameter#3...
				app.Call("murmur", nil, fmt.Sprintf("this is %d speaking", i), 10, 100*time.Millisecond),
			))
	}

	// wait until those tasks are done
	for _, v := range results {
		err = v.Wait(0)
		if err != nil {
			return
		}
	}

	// release resource
	err = app.Close()
	if err != nil {
		return
	}
}
예제 #2
0
func (ts *DingoMultiAppTestSuite) TestSameID() {
	var (
		err          error
		countOfTasks = 5
		reports      = make([][]*dingo.Result, 0, len(ts.Callers))
		fn           = func(n int, msg string) (int, string) {
			return n + 1000, "the msg: " + msg
		}
	)
	defer func() {
		ts.Nil(err)
	}()

	// prepare caller
	for k, v := range ts.Callers {
		name := fmt.Sprintf("TestSameID.%v", k)

		ts.register(name, fn)
		ts.allocate(name, 2, 2)

		err = v.AddIDMaker(101, &dingo.SeqIDMaker{})
		if err != nil {
			return
		}
		err = v.SetIDMaker(name, 101)
		if err != nil {
			return
		}

		rs := []*dingo.Result{}
		for i := 0; i < countOfTasks; i++ {
			rs = append(rs, dingo.NewResult(
				v.Call(
					name, nil,
					k*100+i, fmt.Sprintf("%d", k*100+i),
				)))
		}
		reports = append(reports, rs)
	}

	// checking result
	received := 0
	defer func() {
		ts.Equal(countOfTasks*len(ts.Callers), received)
	}()
	for k, rs := range reports {
		for i, r := range rs {
			err = r.Wait(0)
			if err != nil {
				return
			}
			ts.True(r.Last.OK())
			ts.Equal(1000+k*100+i, r.Last.Return()[0].(int))
			ts.Equal(fmt.Sprintf("the msg: %d", k*100+i), r.Last.Return()[1].(string))
			received++
		}
	}
}
예제 #3
0
func BenchmarkLocal(b *testing.B) {
	var (
		err   error
		count = 1
		msg   = "test string"
	)
	defer func() {
		if err != nil {
			b.Fatalf("failed: %v\n", err)
		}
	}()

	app, err := dingo.NewApp("local", nil)
	if err != nil {
		return
	}

	err = app.Register("myWork", testWork)
	if err != nil {
		return
	}

	_, err = app.Allocate("myWork", 10, 3)
	if err != nil {
		return
	}

	// setup for invoker
	err = app.AddMarshaller(101, &struct {
		dingo.GobMarshaller
		testMyInvoker
	}{
		dingo.GobMarshaller{},
		testMyInvoker{},
	})
	if err != nil {
		return
	}
	err = app.SetMarshaller("myWork", 101, 101)
	if err != nil {
		return
	}

	// setup for idmaker
	err = app.AddIDMaker(101, &dingo.SeqIDMaker{})
	if err != nil {
		return
	}
	err = app.SetIDMaker("myWork", 101)
	if err != nil {
		return
	}

	// reset timer for preparation
	b.ResetTimer()

	var result *dingo.Result
	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			result = dingo.NewResult(app.Call("myWork", nil, count, msg))
			result.Wait(0)
		}
	})
}
예제 #4
0
func (ts *DingoSingleAppTestSuite) TestSameID() {
	// tasks of different name have the same IDs
	var (
		err                error
		countOfConcurrency = 12
		countOfTasks       = 5
		results            = make([][]*dingo.Result, countOfConcurrency)
		wait               sync.WaitGroup
	)
	defer func() {
		ts.Nil(err)
	}()
	fn := func(n int, msg string) (int, string) {
		return n + 1000, "the msg: " + msg
	}

	for i := 0; i < countOfConcurrency; i++ {
		name := fmt.Sprintf("TestSameID.%d", i)
		err = ts.app.Register(name, fn)
		if err != nil {
			return
		}
		err = ts.app.AddIDMaker(100+i, &dingo.SeqIDMaker{})
		if err != nil {
			return
		}
		err = ts.app.SetIDMaker(name, 100+i)
		if err != nil {
			return
		}
		err = ts.app.SetOption(name, dingo.DefaultOption().MonitorProgress(true))
		if err != nil {
			return
		}
		_, err = ts.app.Allocate(name, 5, 3)
		if err != nil {
			return
		}
	}

	// send tasks in parellel
	wait.Add(countOfConcurrency)
	{
		for i := 0; i < countOfConcurrency; i++ {
			go func(idx int, name string) {
				defer wait.Done()
				for j := 0; j < countOfTasks; j++ {
					results[idx] = append(
						results[idx],
						dingo.NewResult(
							ts.app.Call(
								name, nil,
								idx*countOfConcurrency+j, fmt.Sprintf("%d", j),
							)))
				}
			}(i, fmt.Sprintf("TestSameID.%d", i))
		}
	}
	wait.Wait()

	// receiving reports
	received := 0
	defer func() {
		ts.Equal(countOfConcurrency*countOfTasks, received)
	}()
	for i, v := range results {
		for j, r := range v {
			err = r.Wait(0)
			if err != nil {
				return
			}

			ts.Equal(i*countOfConcurrency+j+1000, r.Last.Return()[0].(int))
			ts.Equal(fmt.Sprintf("the msg: %d", j), r.Last.Return()[1].(string))
			received++
		}
	}
}
예제 #5
0
func ExampleApp_Use_caller() {
	/*
		import (
			"fmt"
			"time"

			"github.com/mission-liao/dingo"
			"github.com/mission-liao/dingo/amqp"
		)
	*/
	// this example demostrate a caller based on AMQP, used along with ExampleApp_Use_worker
	// make sure you install a rabbitmq server locally.
	var err error
	defer func() {
		if err != nil {
			fmt.Printf("%v\n", err)
		}
	}()

	// an App in remote mode
	app, err := dingo.NewApp("remote", nil)
	if err != nil {
		return
	}

	// attach an AMQP producer to publish your tasks
	broker, err := dgamqp.NewBroker(dgamqp.DefaultAmqpConfig())
	if err != nil {
		return
	}
	_, _, err = app.Use(broker, dingo.ObjT.Producer)
	if err != nil {
		return
	}

	// attach an AMQP store to receive reports from datastores.
	backend, err := dgamqp.NewBackend(dgamqp.DefaultAmqpConfig())
	if err != nil {
		return
	}
	_, _, err = app.Use(backend, dingo.ObjT.Store)
	if err != nil {
		return
	}

	// register a work function that murmur
	err = app.Register("murmur", func(speech *struct {
		Prologue string
		Script   []string
	}, interval time.Duration) (countOfSentence int) {
		// speak the prologue
		fmt.Printf("%v:\n", speech.Prologue)
		countOfSentence++

		// speak the script
		for _, v := range speech.Script {
			<-time.After(interval)
			fmt.Printf("%v\n", v)
			countOfSentence++
		}

		// return the total sentence we talked
		return
	})
	if err != nil {
		return
	}

	// compose a script to talk
	script := &struct {
		Prologue string
		Script   []string
	}{
		Script: []string{
			"Today, I'm announcing this library.",
			"It should be easy to use, ",
			"and fun to play with.",
			"Merry X'mas.",
		},
	}

	// invoke 20 tasks
	results := []*dingo.Result{}
	for i := 0; i < 20; i++ {
		script.Prologue = fmt.Sprintf("this is %d speaking", i)
		results = append(results,
			dingo.NewResult(
				// name, option, parameter#1, parameter#2 ...
				app.Call("murmur", nil, script, 100*time.Millisecond),
			))
	}

	// wait until those tasks are done
	for _, v := range results {
		err = v.Wait(0)
		if err != nil {
			return
		}

		// result is accessible
		fmt.Printf("one worker spoke %v sentences\n", v.Last.Return()[0].(int))
	}

	// release resource
	err = app.Close()
	if err != nil {
		return
	}
}
예제 #6
0
func ExampleCustomMarshaller() {
	/*
		import (
			"encoding/json"
			"fmt"

			"github.com/mission-liao/dingo"
		)
	*/
	// this example demonstrate the usage of using a
	// customized marshaller by encoding every parameter
	// in JSON.
	// And invoke it with customized invoker
	var err error
	defer func() {
		if err != nil {
			fmt.Printf("%v\n", err)
		}
	}()

	// an App in remote mode, with local backend/broker
	app, err := dingo.NewApp("remote", nil)
	if err != nil {
		return
	}

	// attach a local broker.
	broker, err := dingo.NewLocalBroker(dingo.DefaultConfig(), nil)
	if err != nil {
		return
	}
	_, _, err = app.Use(broker, dingo.ObjT.Default)
	// attach a local backend
	backend, err := dingo.NewLocalBackend(dingo.DefaultConfig(), nil)
	if err != nil {
		return
	}
	_, _, err = app.Use(backend, dingo.ObjT.Default)
	if err != nil {
		return
	}

	// register customize marshaller & invoker
	err = app.AddMarshaller(101, &struct {
		testMyInvoker3
		dingo.CustomMarshaller
	}{
		testMyInvoker3{},
		dingo.CustomMarshaller{Codec: &testCustomMarshallerCodec{}},
	})
	if err != nil {
		return
	}

	// register worker function
	err = app.Register("concat", func(words []string) (ret string) {
		for _, v := range words {
			ret = ret + v
		}
		return
	})
	if err != nil {
		return
	}

	// change marshaller of worker function
	err = app.SetMarshaller("concat", 101, 101)
	if err != nil {
		return
	}

	// allocate workers
	_, err = app.Allocate("concat", 1, 1)
	if err != nil {
		return
	}

	// trigger the fire...
	result := dingo.NewResult(app.Call("concat", nil, []string{"Merry ", "X", "'mas"}))
	err = result.Wait(0)
	if err != nil {
		return
	}
	result.OnOK(func(ret string) {
		fmt.Printf("%v\n", ret)
	})

	err = app.Close()
	if err != nil {
		return
	}
}