Senior
// Task 3 // Describe what problem this code solves // What problems are there in this solution? // How would you rewrite this code? var c int type Trace struct { // Some fields here } type Sender interface { Send(Trace) } func Do(sender Sender, tr Trace) { c++ if c == 100 { sender.Send(tr) c = 0 } }
sobes.tech AI
Answer from AI
This code solves the problem of periodically sending a Trace object through the Sender interface after accumulating 100 calls to the Do function.
Problems with this solution:
- Global variable c: Using a global variable to count calls is not thread-safe and can lead to data races when Do is called in parallel.
- Lack of synchronization: There are no mutexes or other protection mechanisms, making the code unsafe in a multithreaded environment.
- Rigid logic: Sending occurs exactly on the 100th call, with no flexibility to change the threshold or reset the counter.
- No error handling: The Send method does not return an error, and it cannot be handled.
How to rewrite:
- Encapsulate the counter in a structure with a mutex for thread safety.
- Make the send threshold configurable.
- Add error handling.
Example of rewritten code:
type Trace struct {
// fields
}
type Sender interface {
Send(Trace) error
}
type SenderWithCounter struct {
sender Sender
count int
limit int
mu sync.Mutex
}
func NewSenderWithCounter(s Sender, limit int) *SenderWithCounter {
return &SenderWithCounter{sender: s, limit: limit}
}
func (swc *SenderWithCounter) Do(tr Trace) error {
swc.mu.Lock()
defer swc.mu.Unlock()
swc.count++
if swc.count >= swc.limit {
err := swc.sender.Send(tr)
if err != nil {
return err
}
swc.count = 0
}
return nil
}
This approach ensures safety in concurrent use and flexible configuration.