157 lines
6.0 KiB
Go
157 lines
6.0 KiB
Go
package tmobile
|
|
|
|
import (
|
|
"context"
|
|
"math/rand"
|
|
"strconv"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/fiskerinc/cloud-services/pkg/grpc/sms"
|
|
)
|
|
|
|
// Want to make a client simulator that has a delay for each message, along with a chance of failure
|
|
// For use with just await sms testing
|
|
type tmobileSimulator struct {
|
|
messages map[string]fakeMessage
|
|
sy sync.Mutex
|
|
count int
|
|
FailPercentage int // 10 = 10% chance of failure
|
|
AVGDeliveryTime time.Duration // lets do two seconds
|
|
Deviation float64 // The number of seconds we can deviate by
|
|
Rando *rand.Rand // Using a set seed so we can have consistent results with our random messages
|
|
filter ICCIDFilter
|
|
}
|
|
|
|
// ChangeDeviceStatus implements TMobClienter.
|
|
func (ts *tmobileSimulator) ChangeDeviceStatus(ctx context.Context, cda ChangeDeviceActivation) (err error) {
|
|
panic("unimplemented")
|
|
}
|
|
|
|
type fakeMessage struct {
|
|
finishTime time.Time
|
|
//status string // Set the time that the message will resolve, and then it will return this resolution. If blank, the message is not going to be delivered within 5 seconds
|
|
}
|
|
|
|
// avgDeliveryTime is time in seconds
|
|
func newTMboileSimulator() (tms tmobileSimulator) {
|
|
tms.messages = make(map[string]fakeMessage)
|
|
tms.Rando = rand.New(rand.NewSource(99))
|
|
tms.FailPercentage = 5 // 5% chance of a message not being delivered, so 10,000 will have 500 failed
|
|
tms.Deviation = 2 // How many seconds, maybe don't use this
|
|
tms.AVGDeliveryTime = time.Second * 2 // On average take 2ish seconds to deliver the message
|
|
return
|
|
}
|
|
|
|
// AccessToken implements TMobClienter.
|
|
func (*tmobileSimulator) AccessToken(ctx context.Context) (out *AccessTokenResponse, err error) {
|
|
out = &AccessTokenResponse{}
|
|
out.ExpiresIn = 500000
|
|
return
|
|
}
|
|
|
|
// ChangeRatePlan implements TMobClienter.
|
|
func (*tmobileSimulator) ChangeRatePlan(context.Context, *ChangeRatePlanRequest) (*ChangeRatePlanResponse, error) {
|
|
panic("unimplemented")
|
|
}
|
|
|
|
// CustomAttributes implements TMobClienter.
|
|
func (*tmobileSimulator) CustomAttributes(context.Context, *CustomAtributesRequest) (*CustomAtributesResponse, error) {
|
|
panic("unimplemented")
|
|
}
|
|
|
|
// Details implements TMobClienter.
|
|
func (ts *tmobileSimulator) Details(ctx context.Context, ID string) (out *SMSDetailsResponse, err error) {
|
|
out = &SMSDetailsResponse{}
|
|
msg := ts.messages[ID]
|
|
if msg.finishTime.IsZero() {
|
|
out.Status = "Pending"
|
|
return
|
|
}
|
|
//-cpuprofile cpu.out
|
|
if time.Now().After(msg.finishTime) {
|
|
out.Status = "Delivered"
|
|
} else {
|
|
out.Status = "Pending"
|
|
}
|
|
|
|
time.Sleep(time.Millisecond * 40)
|
|
return
|
|
}
|
|
|
|
// DeviceDetails implements TMobClienter.
|
|
func (*tmobileSimulator) DeviceDetails(context.Context, *DeviceDetailsRequest) (*DeviceDetailsResponse, error) {
|
|
panic("unimplemented")
|
|
}
|
|
|
|
// GetProducts implements TMobClienter.
|
|
func (*tmobileSimulator) GetProducts(context.Context, *sms.GetAvailableProductsRequest) (*sms.GetAvailableProductsResponse, error) {
|
|
panic("unimplemented")
|
|
}
|
|
|
|
// SendSMS implements TMobClienter.
|
|
// Call this synchronously as we are using a non-locking map and non-locked index count
|
|
func (ts *tmobileSimulator) SendSMS(ctx context.Context, in *SendSMSRequest) (out *SendSMSResponse, err error) {
|
|
ts.sy.Lock()
|
|
defer ts.sy.Unlock()
|
|
out = &SendSMSResponse{}
|
|
ts.messages[strconv.Itoa(ts.count)] = ts.randomDelivery()
|
|
out.SmsMessageID = strconv.Itoa(ts.count)
|
|
ts.count += 1
|
|
return
|
|
}
|
|
|
|
func (ts *tmobileSimulator) randomDelivery() (msg fakeMessage) {
|
|
if ts.Rando.Intn(100) <= ts.FailPercentage {
|
|
return
|
|
}
|
|
|
|
// 0 -> .99 of deviation
|
|
// 0:Deviation Value - 1/2 deviation = -.5 deviation -> .5 deviation
|
|
// I think its okay that the time is only going to take longer, no real need for shorter messages
|
|
ranomometer := (ts.Rando.Float64() * ts.Deviation)
|
|
// Actually don't need the status for this test. We have the pending unless its delivered. WE don't really see the failed to delivery message
|
|
msg.finishTime = time.Now().Add(ts.AVGDeliveryTime + time.Duration(ranomometer))
|
|
return
|
|
}
|
|
|
|
// SetAccessToken implements TMobClienter.
|
|
func (*tmobileSimulator) SetAccessToken(accessToken string) {
|
|
}
|
|
|
|
// SetFilter implements TMobClienter.
|
|
func (ts *tmobileSimulator) SetFilter(filter []string) {
|
|
ts.filter = ICCIDFilter{
|
|
filter: filter,
|
|
}
|
|
}
|
|
|
|
var _ TMobClienter = new(tmobileSimulator)
|
|
|
|
// with the channel instead of default
|
|
//BenchmarkSMSWrapper-16 1 5009644871 ns/op 3096536 B/op 45650 allocs/op
|
|
// flat flat% sum% cum cum%
|
|
// 50ms 31.25% 31.25% 50ms 31.25% runtime.kevent
|
|
// 40ms 25.00% 56.25% 40ms 25.00% runtime.pthread_cond_wait
|
|
// 20ms 12.50% 68.75% 20ms 12.50% runtime.pthread_cond_signal
|
|
// 10ms 6.25% 75.00% 10ms 6.25% runtime.(*mspan).init
|
|
// 10ms 6.25% 81.25% 20ms 12.50% runtime.mallocgc
|
|
// 10ms 6.25% 87.50% 10ms 6.25% runtime.read
|
|
// 10ms 6.25% 93.75% 10ms 6.25% runtime.usleep
|
|
// 10ms 6.25% 100% 10ms 6.25% runtime.write1
|
|
// 0 0% 100% 20ms 12.50% github.com/fiskerinc/cloud-services/pkg/tmobile.(*SMSClient).SendSMS
|
|
// 0 0% 100% 10ms 6.25% github.com/fiskerinc/cloud-services/pkg/tmobile.(*tmobileSimulator).SendSMS
|
|
// with default
|
|
//BenchmarkSMSWrapper-16 1 5110808221 ns/op 2923960 B/op 43176 allocs/op no major difference
|
|
// flat flat% sum% cum cum%
|
|
// 50ms 45.45% 45.45% 50ms 45.45% runtime.pthread_cond_wait
|
|
// 20ms 18.18% 63.64% 20ms 18.18% runtime.pthread_cond_signal
|
|
// 10ms 9.09% 72.73% 10ms 9.09% runtime.arenaIndex (inline)
|
|
// 10ms 9.09% 81.82% 10ms 9.09% runtime.kevent
|
|
// 10ms 9.09% 90.91% 10ms 9.09% runtime.stackpoolalloc
|
|
// 10ms 9.09% 100% 10ms 9.09% runtime.usleep
|
|
// 0 0% 100% 10ms 9.09% github.com/fiskerinc/cloud-services/pkg/tmobile.BenchmarkSMSWrapper
|
|
// 0 0% 100% 10ms 9.09% runtime.copystack
|
|
// 0 0% 100% 10ms 9.09% runtime.findObject
|
|
// 0 0% 100% 60ms 54.55% runtime.findRunnable
|