lifetime.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. package sessions
  2. import (
  3. "sync"
  4. "time"
  5. "github.com/kataras/iris/context"
  6. )
  7. // LifeTime controls the session expiration datetime.
  8. type LifeTime struct {
  9. // Remember, tip for the future:
  10. // No need of gob.Register, because we embed the time.Time.
  11. // And serious bug which has a result of me spending my whole evening:
  12. // Because of gob encoding it doesn't encodes/decodes the other fields if time.Time is embedded
  13. // (this should be a bug(go1.9-rc1) or not. We don't care atm)
  14. time.Time
  15. timer *time.Timer
  16. mu sync.RWMutex
  17. }
  18. // Begin will begin the life based on the time.Now().Add(d).
  19. // Use `Continue` to continue from a stored time(database-based session does that).
  20. func (lt *LifeTime) Begin(d time.Duration, onExpire func()) {
  21. if d <= 0 {
  22. return
  23. }
  24. lt.mu.Lock()
  25. lt.Time = time.Now().Add(d)
  26. lt.timer = time.AfterFunc(d, onExpire)
  27. lt.mu.Unlock()
  28. }
  29. // Revive will continue the life based on the stored Time.
  30. // Other words that could be used for this func are: Continue, Restore, Resc.
  31. func (lt *LifeTime) Revive(onExpire func()) {
  32. if lt.Time.IsZero() {
  33. return
  34. }
  35. now := time.Now()
  36. if lt.Time.After(now) {
  37. d := lt.Time.Sub(now)
  38. lt.mu.Lock()
  39. lt.timer = time.AfterFunc(d, onExpire)
  40. lt.mu.Unlock()
  41. }
  42. }
  43. // Shift resets the lifetime based on "d".
  44. func (lt *LifeTime) Shift(d time.Duration) {
  45. lt.mu.Lock()
  46. if d > 0 && lt.timer != nil {
  47. lt.Time = time.Now().Add(d)
  48. lt.timer.Reset(d)
  49. }
  50. lt.mu.Unlock()
  51. }
  52. // ExpireNow reduce the lifetime completely.
  53. func (lt *LifeTime) ExpireNow() {
  54. lt.mu.Lock()
  55. lt.Time = context.CookieExpireDelete
  56. if lt.timer != nil {
  57. lt.timer.Stop()
  58. }
  59. lt.mu.Unlock()
  60. }
  61. // HasExpired reports whether "lt" represents is expired.
  62. func (lt *LifeTime) HasExpired() bool {
  63. if lt.IsZero() {
  64. return false
  65. }
  66. return lt.Time.Before(time.Now())
  67. }
  68. // DurationUntilExpiration returns the duration until expires, it can return negative number if expired,
  69. // a call to `HasExpired` may be useful before calling this `Dur` function.
  70. func (lt *LifeTime) DurationUntilExpiration() time.Duration {
  71. return time.Until(lt.Time)
  72. }