How to maintain state or queue of requests in Web API

后端 未结 6 1985
清歌不尽
清歌不尽 2020-12-13 07:39

I have situation, where I have to receive requests in a Web API method, queue those request and then send the bulk to a database (Solr instance).

I am not really su

6条回答
  •  一向
    一向 (楼主)
    2020-12-13 08:12

    public class ThresholdBuffer
    {
        private ConcurrentBag _buffer;
    
        private int _threshold;
    
        public ThresholdBuffer(int threshold)
        {
            _threshold = threshold;
            _buffer = new ConcurrentBag();
        }
    
        public void Add(T item)
        {
            _buffer.Add(item);
    
            if(_buffer.Count >= _threshold)
            {
                Recycle();
            }
        }
    
        public void Recycle()
        {
            var value = Interlocked.Exchange>(ref _buffer, new ConcurrentBag());
    //flush value 
        }
    }
    
    1. Create flushing logic
    2. At Application_Start(Global.asax) event create ThresholdBuffer and store it in Application, Static field, etc
    3. Call Add method
    4. At Application_End manual call Recycle

    You may add locking logic in Recycle to prevent multiple ConcurrentBag creation and flushing nearly empty bag. But my opinion is this is less evil than lock.

    Update. Lock free without aditional ConcurrentBag creation

    public class ThresholdBuffer
    {
        private ConcurrentBag _buffer;
    
        private int _copacity;
    
        private int _threshold;
    
        public ThresholdBuffer(int threshold)
        {
            _threshold = threshold;
            _copacity = 0;
            _buffer = new ConcurrentBag();
        }
    
        public void Add(T item)
        {
            _buffer.Add(item);
            if (Interlocked.Increment(ref _copacity) == _threshold)
            {
                Recycle();
            }
        }
    
        public void Recycle()
        {
            var value4flasshing = Interlocked.Exchange>(ref _buffer, new ConcurrentBag());
            Thread.VolatileWrite(ref _copacity, 0);
        }
    }
    

    ps You may use any ConcurrentCollection instead of ConcurrentBag

提交回复
热议问题