go-channel.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package common
  2. import (
  3. "fmt"
  4. "runtime/debug"
  5. "time"
  6. )
  7. func SafeGoroutine(f func()) {
  8. go func() {
  9. defer func() {
  10. if r := recover(); r != nil {
  11. SysError(fmt.Sprintf("child goroutine panic occured: error: %v, stack: %s", r, string(debug.Stack())))
  12. }
  13. }()
  14. f()
  15. }()
  16. }
  17. func SafeSendBool(ch chan bool, value bool) (closed bool) {
  18. defer func() {
  19. // Recover from panic if one occured. A panic would mean the channel was closed.
  20. if recover() != nil {
  21. closed = true
  22. }
  23. }()
  24. // This will panic if the channel is closed.
  25. ch <- value
  26. // If the code reaches here, then the channel was not closed.
  27. return false
  28. }
  29. func SafeSendString(ch chan string, value string) (closed bool) {
  30. defer func() {
  31. // Recover from panic if one occured. A panic would mean the channel was closed.
  32. if recover() != nil {
  33. closed = true
  34. }
  35. }()
  36. // This will panic if the channel is closed.
  37. ch <- value
  38. // If the code reaches here, then the channel was not closed.
  39. return false
  40. }
  41. // SafeSendStringTimeout send, return true, else return false
  42. func SafeSendStringTimeout(ch chan string, value string, timeout int) (closed bool) {
  43. defer func() {
  44. // Recover from panic if one occured. A panic would mean the channel was closed.
  45. if recover() != nil {
  46. closed = false
  47. }
  48. }()
  49. // This will panic if the channel is closed.
  50. select {
  51. case ch <- value:
  52. return true
  53. case <-time.After(time.Duration(timeout) * time.Second):
  54. return false
  55. }
  56. }