github.com/gdamore/mangos@v1.4.0/util.go (about) 1 // Copyright 2015 The Mangos Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use file except in compliance with the License. 5 // You may obtain a copy of the license at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package mangos 16 17 import ( 18 "fmt" 19 "runtime" 20 "strings" 21 "time" 22 ) 23 24 // mkTimer creates a timer based upon a duration. If however 25 // a zero valued duration is passed, then a nil channel is passed 26 // i.e. never selectable. This allows the output to be readily used 27 // with deadlines in network connections, etc. 28 func mkTimer(deadline time.Duration) <-chan time.Time { 29 30 if deadline == 0 { 31 return nil 32 } 33 34 return time.After(deadline) 35 } 36 37 var debug = true 38 39 func debugf(format string, args ...interface{}) { 40 if debug { 41 _, file, line, ok := runtime.Caller(1) 42 if !ok { 43 file = "<?>" 44 line = 0 45 } else { 46 if i := strings.LastIndex(file, "/"); i >= 0 { 47 file = file[i+1:] 48 } 49 } 50 fmt.Printf("DEBUG: %s:%d [%s]: %s\n", file, line, 51 time.Now().String(), fmt.Sprintf(format, args...)) 52 } 53 } 54 55 // DrainChannel waits for the channel of Messages to finish 56 // emptying (draining) for up to the expiration. It returns 57 // true if the drain completed (the channel is empty), false otherwise. 58 func DrainChannel(ch chan<- *Message, expire time.Time) bool { 59 var dur = time.Millisecond * 10 60 61 for { 62 if len(ch) == 0 { 63 return true 64 } 65 now := time.Now() 66 if now.After(expire) { 67 return false 68 } 69 // We sleep the lesser of the remaining time, or 70 // 10 milliseconds. This polling is kind of suboptimal for 71 // draining, but its far far less complicated than trying to 72 // arrange special messages to force notification, etc. 73 dur = expire.Sub(now) 74 if dur > time.Millisecond*10 { 75 dur = time.Millisecond * 10 76 } 77 time.Sleep(dur) 78 } 79 }