|
|
|
@ -10,19 +10,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
package main
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const MAX_SECONDS = 10
|
|
|
|
|
|
|
|
|
|
|
|
// User defines the UserModel. Use this to check whether a User is a
|
|
|
|
// User defines the UserModel. Use this to check whether a User is a
|
|
|
|
// Premium user or not
|
|
|
|
// Premium user or not
|
|
|
|
type User struct {
|
|
|
|
type User struct {
|
|
|
|
ID int
|
|
|
|
ID int
|
|
|
|
IsPremium bool
|
|
|
|
IsPremium bool
|
|
|
|
TimeUsed int64 // in seconds
|
|
|
|
TimeUsed int64 // in seconds
|
|
|
|
|
|
|
|
mu sync.Mutex
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// HandleRequest runs the processes requested by users. Returns false
|
|
|
|
// HandleRequest runs the processes requested by users. Returns false
|
|
|
|
// if process had to be killed
|
|
|
|
// if process had to be killed
|
|
|
|
func HandleRequest(process func(), u *User) bool {
|
|
|
|
func HandleRequest(process func(), u *User) bool {
|
|
|
|
|
|
|
|
finished := make(chan bool)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// unfortunately we won't be able to kill the goroutine.
|
|
|
|
|
|
|
|
// So a call to process() may exceeds MAX_SECONDS duration.
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
process()
|
|
|
|
process()
|
|
|
|
|
|
|
|
finished <- true
|
|
|
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
select {
|
|
|
|
|
|
|
|
case <-finished:
|
|
|
|
return true
|
|
|
|
return true
|
|
|
|
|
|
|
|
case <-time.After(MAX_SECONDS * time.Second):
|
|
|
|
|
|
|
|
if u.IsPremium {
|
|
|
|
|
|
|
|
<-finished
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
u.mu.Lock()
|
|
|
|
|
|
|
|
u.TimeUsed += MAX_SECONDS
|
|
|
|
|
|
|
|
u.mu.Unlock()
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
func main() {
|
|
|
|
|