Created
January 26, 2018 11:12
-
-
Save mngmntt/24e9bdcaf9a5d43cdf331e7d7415fa87 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package bpool | |
import ( | |
"bytes" | |
) | |
type SizedBufferPool struct { | |
c chan *bytes.Buffer | |
a int | |
} | |
// SizedBufferPool creates a new BufferPool bounded to the given size. | |
// size defines the number of buffers to be retained in the pool and alloc sets | |
// the initial capacity of new buffers to minimize calls to make(). | |
func NewSizedBufferPool(size int, alloc int) (bp *SizedBufferPool) { | |
return &SizedBufferPool{ | |
c: make(chan *bytes.Buffer, size), | |
a: alloc, | |
} | |
} | |
// Get gets a Buffer from the SizedBufferPool, or creates a new one if none are | |
// available in the pool. Buffers have a pre-allocated capacity. | |
func (bp *SizedBufferPool) Get() (b *bytes.Buffer) { | |
select { | |
case b = <-bp.c: | |
// reuse existing buffer | |
default: | |
// create new buffer | |
b = bytes.NewBuffer(make([]byte, 0, bp.a)) | |
} | |
return | |
} | |
// Put returns the given Buffer to the SizedBufferPool. | |
func (bp *SizedBufferPool) Put(b *bytes.Buffer) { | |
b.Reset() | |
// Release buffers over our maximum capacity and re-create a pre-sized | |
// buffer to replace it. | |
if cap(b.Bytes()) > bp.a { | |
b = bytes.NewBuffer(make([]byte, 0, bp.a)) | |
} | |
select { | |
case bp.c <- b: | |
default: // Discard the buffer if the pool is full. | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var bytePool = bpool.NewSizedBufferPool(1000, 25000) | |
// QuerySolr returns the result of request to solr database (as struct) | |
func QuerySolr(country string, filter *SolrProductFilter, parser SolrParser) error { | |
data := url.Values{} | |
filter.BuildSolrQuery(data.Add) | |
logger.GetCtx(country, nil).Debugf("Solr Query: %s", data.Encode()) | |
req, err := http.NewRequest("POST", config.SolrCatalogURLs[country], strings.NewReader(data.Encode())) | |
req.Header.Add("Content-Type", "application/x-www-form-urlencoded") | |
response, err := netClient.Do(req) | |
if response != nil { | |
defer response.Body.Close() | |
} | |
if err != nil { | |
logger.GetCtx(country, nil).Errorf("Solr client: %v", err) | |
return err | |
} | |
dataBuf := bytePool.Get() | |
defer bytePool.Put(dataBuf) | |
_, err = dataBuf.ReadFrom(response.Body) | |
if err != nil { | |
logger.GetCtx(country, nil).Errorf("Solr response reader: %v", err) | |
return err | |
} | |
if response.StatusCode != 200 { | |
logger.GetCtx(country, nil).Errorf("Solr: %s", dataBuf) | |
return errors.New("Solr HTTP error") | |
} | |
err = parser.Parse(dataBuf.Bytes()) | |
if err != nil { | |
logger.GetCtx(country, nil).Errorf("Solr response parse: %v", err) | |
return err | |
} | |
io.Copy(ioutil.Discard, response.Body) | |
return nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment