legacywriteflusher.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package writeflusher
  2. import (
  3. "io"
  4. "sync"
  5. )
  6. // Deprecated: use the internal WriteFlusher instead.
  7. // This is the old implementation that lived in ioutils.
  8. // This struct and all funcs below used to live in the pkg/ioutils package
  9. //
  10. // LegacyWriteFlusher wraps the Write and Flush operation ensuring that every write
  11. // is a flush. In addition, the Close method can be called to intercept
  12. // Read/Write calls if the targets lifecycle has already ended.
  13. //
  14. // Deprecated: use the internal writeflusher.WriteFlusher instead
  15. type LegacyWriteFlusher struct {
  16. w io.Writer
  17. flusher flusher
  18. flushed chan struct{}
  19. flushedOnce sync.Once
  20. closed chan struct{}
  21. closeLock sync.Mutex
  22. }
  23. // NewLegacyWriteFlusher returns a new LegacyWriteFlusher.
  24. //
  25. // Deprecated: use the internal writeflusher.NewWriteFlusher() instead
  26. func NewLegacyWriteFlusher(w io.Writer) *LegacyWriteFlusher {
  27. var fl flusher
  28. if f, ok := w.(flusher); ok {
  29. fl = f
  30. } else {
  31. fl = &NopFlusher{}
  32. }
  33. return &LegacyWriteFlusher{w: w, flusher: fl, closed: make(chan struct{}), flushed: make(chan struct{})}
  34. }
  35. // Deprecated: use the internal writeflusher.Write() instead
  36. func (wf *LegacyWriteFlusher) Write(b []byte) (n int, err error) {
  37. select {
  38. case <-wf.closed:
  39. return 0, errWriteFlusherClosed
  40. default:
  41. }
  42. n, err = wf.w.Write(b)
  43. wf.Flush() // every write is a flush.
  44. return n, err
  45. }
  46. // Flush the stream immediately.
  47. //
  48. // Deprecated: use the internal writeflusher.Flush() instead
  49. func (wf *LegacyWriteFlusher) Flush() {
  50. select {
  51. case <-wf.closed:
  52. return
  53. default:
  54. }
  55. wf.flushedOnce.Do(func() {
  56. close(wf.flushed)
  57. })
  58. wf.flusher.Flush()
  59. }
  60. // Flushed returns the state of flushed.
  61. // If it's flushed, return true, or else it return false.
  62. //
  63. // Deprecated: use the internal writeflusher.WriteFlusher instead
  64. func (wf *LegacyWriteFlusher) Flushed() bool {
  65. // BUG(stevvooe): Remove this method. Its use is inherently racy. Seems to
  66. // be used to detect whether or a response code has been issued or not.
  67. // Another hook should be used instead.
  68. var flushed bool
  69. select {
  70. case <-wf.flushed:
  71. flushed = true
  72. default:
  73. }
  74. return flushed
  75. }
  76. // Close closes the write flusher, disallowing any further writes to the
  77. // target. After the flusher is closed, all calls to write or flush will
  78. // result in an error.
  79. //
  80. // Deprecated: use the internal writeflusher.Close() instead
  81. func (wf *LegacyWriteFlusher) Close() error {
  82. wf.closeLock.Lock()
  83. defer wf.closeLock.Unlock()
  84. select {
  85. case <-wf.closed:
  86. return errWriteFlusherClosed
  87. default:
  88. close(wf.closed)
  89. }
  90. return nil
  91. }