From b3ddd5a9b86a8d7b342db74e4d7c628c6d451f46 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Tue, 14 Feb 2012 17:09:28 +0200 Subject: [PATCH] started prepaid processing --- cmd/inquirer/registration.go | 24 ++++++------- cmd/rater/registration.go | 20 +++++------ tariffplans/userbudget.go | 66 ++++++++++++++++++++++++++++++++++ tariffplans/userbudget_test.go | 51 ++++++++++++++++++++++++++ timespans/calldesc.go | 7 ++-- 5 files changed, 142 insertions(+), 26 deletions(-) create mode 100644 tariffplans/userbudget.go create mode 100644 tariffplans/userbudget_test.go diff --git a/cmd/inquirer/registration.go b/cmd/inquirer/registration.go index 67fa83916..a931be6eb 100644 --- a/cmd/inquirer/registration.go +++ b/cmd/inquirer/registration.go @@ -1,7 +1,7 @@ package main import ( - "exp/signal" + "os/signal" "fmt" "log" "net/rpc" @@ -20,19 +20,17 @@ Listens for SIGTERM, SIGINT, SIGQUIT system signals and shuts down all the regis */ func StopSingnalHandler() { log.Print("Handling stop signals...") - sig := <-signal.Incoming - if usig, ok := sig.(os.UnixSignal); ok { - switch usig { - case syscall.SIGTERM, syscall.SIGINT, syscall.SIGQUIT: - log.Printf("Caught signal %v, sending shutdownto raters\n", usig) - var reply string - for i, client := range raterList.clientConnections { - client.Call("Storage.Shutdown", "", &reply) - log.Printf("Shutdown rater %v: %v ", raterList.clientAddresses[i], reply) - } - os.Exit(1) - } + c := make(chan os.Signal) + signal.Notify(c, syscall.SIGTERM, syscall.SIGINT, syscall.SIGQUIT) + + sig := <-c + log.Printf("Caught signal %v, sending shutdownto raters\n", sig) + var reply string + for i, client := range raterList.clientConnections { + client.Call("Storage.Shutdown", "", &reply) + log.Printf("Shutdown rater %v: %v ", raterList.clientAddresses[i], reply) } + os.Exit(1) } /* diff --git a/cmd/rater/registration.go b/cmd/rater/registration.go index ea31747d6..5cce1e9cc 100644 --- a/cmd/rater/registration.go +++ b/cmd/rater/registration.go @@ -1,7 +1,7 @@ package main import ( - "exp/signal" + "os/signal" "github.com/rif/cgrates/timespans" "log" "net/rpc" @@ -14,16 +14,14 @@ Listens for the SIGTERM, SIGINT, SIGQUIT system signals and gracefuly unregiste */ func StopSingnalHandler(server, listen *string, sg timespans.StorageGetter) { log.Print("Handling stop signals...") - sig := <-signal.Incoming - if usig, ok := sig.(os.UnixSignal); ok { - switch usig { - case syscall.SIGTERM, syscall.SIGINT, syscall.SIGQUIT: - log.Printf("Caught signal %v, unregistering from server\n", usig) - unregisterFromServer(server, listen) - sg.Close() - os.Exit(1) - } - } + c := make(chan os.Signal) + signal.Notify(c, syscall.SIGTERM, syscall.SIGINT, syscall.SIGQUIT) + sig := <-c + + log.Printf("Caught signal %v, unregistering from server\n", sig) + unregisterFromServer(server, listen) + sg.Close() + os.Exit(1) } /* diff --git a/tariffplans/userbudget.go b/tariffplans/userbudget.go new file mode 100644 index 000000000..386fe518a --- /dev/null +++ b/tariffplans/userbudget.go @@ -0,0 +1,66 @@ +package tariffplans + +import ( + "math" + "log" +) + +type UserBudget struct { + id string + minuteBuckets []*MinuteBucket + credit float64 + tariffPlan *TariffPlan + resetDayOfTheMonth int +} + +/* +Returns user's avaliable minutes for the specified destination +*/ +func (ub *UserBudget) GetSecondsForPrefix(prefix string) (seconds int) { + if len(ub.minuteBuckets) == 0{ + log.Print("There are no minute buckets to check for user", ub.id) + return + } + bestBucket := ub.minuteBuckets[0] + + for _, mb := range ub.minuteBuckets { + if mb.containsPrefix(prefix) && mb.priority > bestBucket.priority { + bestBucket = mb + } + } + seconds = bestBucket.seconds + if bestBucket.price > 0 { + seconds = int(math.Min(ub.credit / bestBucket.price, float64(seconds))) + } + return +} + +func (ub *UserBudget) GetSecondsForSecondPrice(price float64) (seconds int) { + return +} + +type Destination struct { + id string + prefixes []string +} + +type MinuteBucket struct { + seconds int + priority int + price float64 + destination *Destination +} + +func (mb *MinuteBucket) containsPrefix(prefix string) bool { + for _, p := range mb.destination.prefixes{ + if prefix == p { + return true + } + } + return false +} + +type TariffPlan struct { + minuteBuckets []*MinuteBucket +} + diff --git a/tariffplans/userbudget_test.go b/tariffplans/userbudget_test.go new file mode 100644 index 000000000..dffd0ba8d --- /dev/null +++ b/tariffplans/userbudget_test.go @@ -0,0 +1,51 @@ +package tariffplans + +import ( + "testing" +) + +var ( + nationale = &Destination{id: "nationale", prefixes: []string{"0257", "0256", "0723"}} + retea = &Destination{id: "retea", prefixes: []string{"0723", "0724"}} +) + +func TestGetSeconds(t *testing.T) { + b1 := &MinuteBucket{seconds: 10, priority: 10, destination: nationale} + b2 := &MinuteBucket{seconds: 100, priority: 20, destination: retea} + tf1 := &TariffPlan{minuteBuckets: []*MinuteBucket{b1,b2}} + + ub1 := &UserBudget{id: "rif", minuteBuckets: []*MinuteBucket{b1,b2}, credit: 200, tariffPlan: tf1, resetDayOfTheMonth: 10} + seconds := ub1.GetSecondsForPrefix("0723") + expected := 100 + if seconds != expected { + t.Errorf("Expected %v was %v", expected, seconds) + } +} + +func TestGetPricedSeconds(t *testing.T) { + b1 := &MinuteBucket{seconds: 10, price:10, priority: 10, destination: nationale} + b2 := &MinuteBucket{seconds: 100, price:1, priority: 20, destination: retea} + tf1 := &TariffPlan{minuteBuckets: []*MinuteBucket{b1,b2}} + + ub1 := &UserBudget{id: "rif", minuteBuckets: []*MinuteBucket{b1,b2}, credit: 21, tariffPlan: tf1, resetDayOfTheMonth: 10} + seconds := ub1.GetSecondsForPrefix("0723") + expected := 21 + if seconds != expected { + t.Errorf("Expected %v was %v", expected, seconds) + } +} + +/*********************************** Benchmarks *******************************/ + +func BenchmarkActivationPeriodRestore(b *testing.B) { + b.StopTimer() + b1 := &MinuteBucket{seconds: 10, price:10, priority: 10, destination: nationale} + b2 := &MinuteBucket{seconds: 100, price:1, priority: 20, destination: retea} + tf1 := &TariffPlan{minuteBuckets: []*MinuteBucket{b1,b2}} + + ub1 := &UserBudget{id: "rif", minuteBuckets: []*MinuteBucket{b1,b2}, credit: 21, tariffPlan: tf1, resetDayOfTheMonth: 10} + b.StartTimer() + for i := 0; i < b.N; i++ { + ub1.GetSecondsForPrefix("0723") + } +} diff --git a/timespans/calldesc.go b/timespans/calldesc.go index b5f0285df..b237fdb04 100644 --- a/timespans/calldesc.go +++ b/timespans/calldesc.go @@ -77,10 +77,12 @@ func (cd *CallDescriptor) splitInTimeSpans() (timespans []*TimeSpan) { } // split on price intervals for i := 0; i < len(timespans); i++ { - for _, interval := range timespans[i].ActivationPeriod.Intervals { + ap := timespans[i].ActivationPeriod + //timespans[i].ActivationPeriod = nil + for _, interval := range ap.Intervals { newTs := timespans[i].SplitByInterval(interval) if newTs != nil { - newTs.ActivationPeriod = timespans[i].ActivationPeriod + newTs.ActivationPeriod = ap timespans = append(timespans, newTs) } } @@ -128,6 +130,7 @@ func (cd *CallDescriptor) GetCost(sg StorageGetter) (result *CallCost, err error if len(timespans) > 0 { connectionFee = timespans[0].Interval.ConnectFee } + cc := &CallCost{TOR: cd.TOR, CstmId: cd.CstmId, Subject: cd.Subject,