vendor: add qingstor-sdk-go for QingStor
This commit is contained in:
parent
f682002b84
commit
466dd22b44
136 changed files with 15952 additions and 1 deletions
176
vendor/github.com/pengsrc/go-shared/reopen/reopen.go
generated
vendored
Normal file
176
vendor/github.com/pengsrc/go-shared/reopen/reopen.go
generated
vendored
Normal file
|
@ -0,0 +1,176 @@
|
|||
package reopen
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Reopener interface defines something that can be reopened.
|
||||
type Reopener interface {
|
||||
Reopen() error
|
||||
}
|
||||
|
||||
// Writer is a writer that also can be reopened.
|
||||
type Writer interface {
|
||||
Reopener
|
||||
io.Writer
|
||||
}
|
||||
|
||||
// WriteCloser is a io.WriteCloser that can also be reopened.
|
||||
type WriteCloser interface {
|
||||
Reopener
|
||||
io.WriteCloser
|
||||
}
|
||||
|
||||
// FileWriter that can also be reopened.
|
||||
type FileWriter struct {
|
||||
// Ensures close/reopen/write are not called at the same time, protects f
|
||||
mu sync.Mutex
|
||||
f *os.File
|
||||
mode os.FileMode
|
||||
name string
|
||||
}
|
||||
|
||||
// Close calls the under lying File.Close().
|
||||
func (f *FileWriter) Close() error {
|
||||
f.mu.Lock()
|
||||
err := f.f.Close()
|
||||
f.mu.Unlock()
|
||||
return err
|
||||
}
|
||||
|
||||
// Reopen the file.
|
||||
func (f *FileWriter) Reopen() error {
|
||||
f.mu.Lock()
|
||||
err := f.reopen()
|
||||
f.mu.Unlock()
|
||||
return err
|
||||
}
|
||||
|
||||
// Write implements the stander io.Writer interface.
|
||||
func (f *FileWriter) Write(p []byte) (int, error) {
|
||||
f.mu.Lock()
|
||||
n, err := f.f.Write(p)
|
||||
f.mu.Unlock()
|
||||
return n, err
|
||||
}
|
||||
|
||||
// reopen with mutex free.
|
||||
func (f *FileWriter) reopen() error {
|
||||
if f.f != nil {
|
||||
f.f.Close()
|
||||
f.f = nil
|
||||
}
|
||||
ff, err := os.OpenFile(f.name, os.O_WRONLY|os.O_APPEND|os.O_CREATE, f.mode)
|
||||
if err != nil {
|
||||
f.f = nil
|
||||
return err
|
||||
}
|
||||
f.f = ff
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewFileWriter opens a file for appending and writing and can be reopened.
|
||||
// It is a ReopenWriteCloser...
|
||||
func NewFileWriter(name string) (*FileWriter, error) {
|
||||
// Standard default mode
|
||||
return NewFileWriterMode(name, 0644)
|
||||
}
|
||||
|
||||
// NewFileWriterMode opens a Reopener file with a specific permission.
|
||||
func NewFileWriterMode(name string, mode os.FileMode) (*FileWriter, error) {
|
||||
writer := FileWriter{
|
||||
f: nil,
|
||||
name: name,
|
||||
mode: mode,
|
||||
}
|
||||
err := writer.reopen()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &writer, nil
|
||||
}
|
||||
|
||||
// BufferedFileWriter is buffer writer than can be reopened.
|
||||
type BufferedFileWriter struct {
|
||||
mu sync.Mutex
|
||||
OrigWriter *FileWriter
|
||||
BufWriter *bufio.Writer
|
||||
}
|
||||
|
||||
// Reopen implement Reopener.
|
||||
func (bw *BufferedFileWriter) Reopen() error {
|
||||
bw.mu.Lock()
|
||||
bw.BufWriter.Flush()
|
||||
|
||||
// Use non-mutex version since we are using this one.
|
||||
err := bw.OrigWriter.reopen()
|
||||
|
||||
bw.BufWriter.Reset(io.Writer(bw.OrigWriter))
|
||||
bw.mu.Unlock()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Close flushes the internal buffer and closes the destination file.
|
||||
func (bw *BufferedFileWriter) Close() error {
|
||||
bw.mu.Lock()
|
||||
bw.BufWriter.Flush()
|
||||
bw.OrigWriter.f.Close()
|
||||
bw.mu.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Write implements io.Writer (and reopen.Writer).
|
||||
func (bw *BufferedFileWriter) Write(p []byte) (int, error) {
|
||||
bw.mu.Lock()
|
||||
n, err := bw.BufWriter.Write(p)
|
||||
|
||||
// Special Case... if the used space in the buffer is LESS than
|
||||
// the input, then we did a flush in the middle of the line
|
||||
// and the full log line was not sent on its way.
|
||||
if bw.BufWriter.Buffered() < len(p) {
|
||||
bw.BufWriter.Flush()
|
||||
}
|
||||
|
||||
bw.mu.Unlock()
|
||||
return n, err
|
||||
}
|
||||
|
||||
// Flush flushes the buffer.
|
||||
func (bw *BufferedFileWriter) Flush() {
|
||||
bw.mu.Lock()
|
||||
bw.BufWriter.Flush()
|
||||
bw.OrigWriter.f.Sync()
|
||||
bw.mu.Unlock()
|
||||
}
|
||||
|
||||
// flushDaemon periodically flushes the log file buffers.
|
||||
func (bw *BufferedFileWriter) flushDaemon(interval time.Duration) {
|
||||
for range time.NewTicker(interval).C {
|
||||
bw.Flush()
|
||||
}
|
||||
}
|
||||
|
||||
const bufferSize = 256 * 1024
|
||||
const flushInterval = 30 * time.Second
|
||||
|
||||
// NewBufferedFileWriter opens a buffered file that is periodically flushed.
|
||||
func NewBufferedFileWriter(w *FileWriter) *BufferedFileWriter {
|
||||
return NewBufferedFileWriterSize(w, bufferSize, flushInterval)
|
||||
}
|
||||
|
||||
// NewBufferedFileWriterSize opens a buffered file with the given size that is periodically
|
||||
// flushed on the given interval.
|
||||
func NewBufferedFileWriterSize(w *FileWriter, size int, flush time.Duration) *BufferedFileWriter {
|
||||
bw := BufferedFileWriter{
|
||||
OrigWriter: w,
|
||||
BufWriter: bufio.NewWriterSize(w, size),
|
||||
}
|
||||
go bw.flushDaemon(flush)
|
||||
return &bw
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue