Module: EventMachine::Protocols::Redis

Defined in:
lib/joffice_redis/redis_method_factory.rb

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(*argv) ⇒ Object



323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
# File 'lib/joffice_redis/redis_method_factory.rb', line 323

def method_missing(*argv)
  name=argv[0].to_s
  p "call #{name} (#{argv[1..argv.length]})"
  if $debug  && false
    p "call #{name} (#{argv[1..argv.length]})" 
    #pp Kernel.caller
    #$log.debug("Redis"){"call #{name} (#{argv[1..argv.length]})"}
    argv[0]=(name=name[0,name.length-1]) if name.end_with?('!')
  end
  if name.end_with?('!')
    argv[0]=name[0,name.length-1]         
    call_command(argv) {|a| }
  else
    c=Fiber.current
    call_command(argv) { |a|  c.resume(a); }
    Fiber.yield
  end      
end

Instance Method Details

#bulk_arrayObject



189
190
191
# File 'lib/joffice_redis/redis_method_factory.rb', line 189

def bulk_array
  @bulk_array||=[]
end

#bulk_expire_arrayObject



197
198
199
# File 'lib/joffice_redis/redis_method_factory.rb', line 197

def bulk_expire_array
  @bulk_expire_array||=[]
end

#bulk_insert?Boolean

Returns:

  • (Boolean)


201
202
203
# File 'lib/joffice_redis/redis_method_factory.rb', line 201

def bulk_insert?
  !@bulk_insert.nil?
end

#bulk_setObject



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/joffice_redis/redis_method_factory.rb', line 226

def bulk_set
  bulk_insert=@bulk_insert.nil?
  begin
    @bulk_insert=true
    yield if block_given?
    if bulk_insert
      @bulk_insert=nil
      del_real(delete_array)
      mset_real(bulk_array)          
      bulk_expire_array.each do |value|                
        call_command(value) { |a| }
      end
    end
  ensure
    if bulk_insert             
      delete_array.clear
      bulk_array.clear
      bulk_expire_array.clear
    end
  end
end

#del_async(*agrs) ⇒ Object Also known as: del!, del, delete



294
295
296
297
298
299
300
301
# File 'lib/joffice_redis/redis_method_factory.rb', line 294

def del_async(*agrs)
  values=agrs.flatten
  if bulk_insert?
    delete_array += values
  else         
    del_real(values)
  end
end

#del_real(keys) ⇒ Object

end set



290
291
292
# File 'lib/joffice_redis/redis_method_factory.rb', line 290

def del_real(keys)         
  call_command(keys.unshift('del')) { |a| } unless keys.empty?        
end

#delete_arrayObject



193
194
195
# File 'lib/joffice_redis/redis_method_factory.rb', line 193

def delete_array
  @delete_array||=[]
end

#expire_async(key, value) ⇒ Object Also known as: expire!, expire



278
279
280
281
282
283
284
# File 'lib/joffice_redis/redis_method_factory.rb', line 278

def expire_async(key, value)
  if bulk_insert?
    bulk_expire_array << ['expire', key, value]
  else          
    call_command(['expire', key, value]) { |a| }
  end
end

#mget(keys) ⇒ Object



307
308
309
310
311
312
313
314
315
316
# File 'lib/joffice_redis/redis_method_factory.rb', line 307

def mget(keys)
  return [] if keys.blank?
  #keys.flatten!
  #return [] if keys.empty?
  #$log.debug("Redis"){"call mget (#{args.inspect})"} if $debug
  
  c=Fiber.current
  call_command(keys.flatten.unshift('mget')) { |a|  c.resume(a); }
  Fiber.yield
end

#mset_async(*args) ⇒ Object Also known as: mset!, mset



267
268
269
270
271
272
273
# File 'lib/joffice_redis/redis_method_factory.rb', line 267

def mset_async(*args)
  if bulk_insert?
    bulk_array+=args          
  else
    mset_real(args)          
  end
end

#mset_real(args) ⇒ Object



262
263
264
265
# File 'lib/joffice_redis/redis_method_factory.rb', line 262

def mset_real(args)      
  argv=args.flatten
  call_command(argv.unshift('mset')) { |a| } unless argv.empty?   
end

#process_cmd(line) ⇒ Object



373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
# File 'lib/joffice_redis/redis_method_factory.rb', line 373

def process_cmd(line)
  puts "*** processing #{line}" if $debug
  # first character of buffer will always be the response type
  reply_type = line[0, 1]
  reply_args = line.slice(1..-3) # remove type character and \r\n
  case reply_type
    
    #e.g. -MISSING
    when MINUS
    @redis_callbacks.shift # throw away the cb?
    if @err_cb
      @err_cb.call(reply_args)
    else
      err = RedisError.new
      err.code = reply_args
      raise err, "Redis server returned error code: #{err.code}"
    end
    
    # e.g. +OK
    when PLUS
    dispatch_response(reply_args)
    
    # e.g. $3\r\nabc\r\n
    # 'bulk' is more complex because it could be part of multi-bulk
    when DOLLAR
    data_len = Integer(reply_args)
    if data_len == -1 # expect no data; return nil
      if @multibulk_n > 0 # we're in the middle of a multibulk reply
        @values << nil
        if @values.size == @multibulk_n # DING, we're done
          dispatch_response(@values)
          @values = []
          @multibulk_n = 0
        end
      else
        dispatch_response(nil)
      end
    elsif @buffer.size >= data_len + 2 # buffer is full of expected data
      if @multibulk_n > 0 # we're in the middle of a multibulk reply
        @values << @buffer.slice!(0, data_len)
        if @values.size == @multibulk_n # DING, we're done
          dispatch_response(@values)
          @values = []
          @multibulk_n = 0
        end
      else # not multibulk
        value = @buffer.slice!(0, data_len)
        dispatch_response(value)
      end
      @buffer.slice!(0,2) # tossing \r\n
    else # buffer isn't full or nil
      # FYI, ParseError puts command back on head of buffer, waits for
      # more data complete buffer
      raise ParserError 
    end
    
    #e.g. :8
    when COLON
    dispatch_response(Integer(reply_args))
    
    #e.g. *2\r\n$1\r\na\r\n$1\r\nb\r\n 
    when ASTERISK
    @multibulk_n = Integer(reply_args)
    dispatch_response(nil) if @multibulk_n == -1 || @multibulk_n == 0
    
    # Whu?
  else
    raise ProtocolError, "reply type not recognized: #{line.strip}"
  end
end

#raw_call_command(args, &blk) ⇒ Object



346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
# File 'lib/joffice_redis/redis_method_factory.rb', line 346

def raw_call_command(args, &blk)
  argv = args.flatten.map{|v| v.to_s}
  
  if MULTI_BULK_COMMANDS[argv.first]
    command = "*#{argv.size}\r\n"
    argv.each do |v|
      command << "$#{get_size(v)}\r\n"
      command << "#{v}\r\n"
    end          
  else
    name = argv[0].downcase
    argv[0] = (ALIASES[name] || name)
    raise "#{name} command is disabled" if DISABLED_COMMANDS[name]
    if argv.length > 2 and BULK_COMMANDS[name]
      bulk=argv[-1]
      argv[-1]=get_size(bulk)
    end
    command = "#{argv.join(' ')}\r\n"
    command << "#{bulk}\r\n" if bulk
  end
  
  puts "*** sending: #{command}" if $debug
  @redis_callbacks << [REPLY_PROCESSOR[argv[0]], blk]
  send_data command
end

#set_async(key, value) ⇒ Object Also known as: set!, set

set



250
251
252
253
254
255
256
257
# File 'lib/joffice_redis/redis_method_factory.rb', line 250

def set_async(key, value)
  if bulk_insert?
    bulk_array << key
    bulk_array << value
  else
    call_command(['set', key, value]) { |a| }
  end
end

#set_remove_if_empty(key_name, value) ⇒ Object



318
319
320
321
# File 'lib/joffice_redis/redis_method_factory.rb', line 318

def set_remove_if_empty(key_name, value)
  set_remove(key_name, value)
  del(key_name) if scard(key_name)==0
end

#support_mset?Boolean

Returns:

  • (Boolean)


342
343
344
# File 'lib/joffice_redis/redis_method_factory.rb', line 342

def support_mset?    
  @support_mset||=version >= "1.1" 
end

#transactionObject

Добавление всех данных в одной транзакции

Redis send:
  MULTI
  COMMAND_1 ...
  COMMAND_2 ...
  COMMAND_N ...
  EXEC or DISCARD


214
215
216
217
218
219
220
221
222
223
224
# File 'lib/joffice_redis/redis_method_factory.rb', line 214

def transaction
  return unless block_given?
  begin
    multi
    yield
    exec
  rescue Exception => e
    discard 
    raise e          
  end
end