@@ -39,18 +39,24 @@ function RedisClient(stream, options) {
39
39
options = JSON . parse ( JSON . stringify ( options || { } ) ) ;
40
40
var self = this ;
41
41
42
+ this . pipeline = 0 ;
43
+ var cork ;
42
44
if ( ! stream . cork ) {
43
- this . pipeline = 0 ;
44
- this . cork = noop ;
45
- this . once ( 'ready' , function ( ) {
46
- self . cork = function ( len ) {
47
- self . pipeline = len ;
48
- self . pipeline_queue = new Queue ( len ) ;
49
- } ;
50
- } ) ;
51
- stream . uncork = noop ;
52
- this . write = this . writeStream ;
45
+ cork = function ( len ) {
46
+ self . pipeline = len ;
47
+ self . pipeline_queue = new Queue ( len ) ;
48
+ } ;
49
+ this . uncork = noop ;
50
+ } else {
51
+ cork = function ( len ) {
52
+ self . pipeline = len ;
53
+ self . pipeline_queue = new Queue ( len ) ;
54
+ self . stream . cork ( ) ;
55
+ } ;
53
56
}
57
+ this . once ( 'ready' , function ( ) {
58
+ self . cork = cork ;
59
+ } ) ;
54
60
55
61
this . stream = stream ;
56
62
this . connection_id = ++ connection_id ;
@@ -131,8 +137,9 @@ RedisClient.prototype.install_stream_listeners = function() {
131
137
} ) ;
132
138
} ;
133
139
134
- RedisClient . prototype . cork = function ( len ) {
135
- this . stream . cork ( ) ;
140
+ RedisClient . prototype . cork = noop ;
141
+ RedisClient . prototype . uncork = function ( ) {
142
+ this . stream . uncork ( ) ;
136
143
} ;
137
144
138
145
RedisClient . prototype . initialize_retry_vars = function ( ) {
@@ -377,7 +384,6 @@ RedisClient.prototype.on_info_cmd = function (err, res) {
377
384
return ;
378
385
}
379
386
380
- var self = this ;
381
387
var obj = { } ;
382
388
var lines = res . toString ( ) . split ( '\r\n' ) ;
383
389
var i = 0 ;
@@ -422,9 +428,9 @@ RedisClient.prototype.on_info_cmd = function (err, res) {
422
428
retry_time = 1000 ;
423
429
}
424
430
debug ( 'Redis server still loading, trying again in ' + retry_time ) ;
425
- setTimeout ( function ( ) {
431
+ setTimeout ( function ( self ) {
426
432
self . ready_check ( ) ;
427
- } , retry_time ) ;
433
+ } , retry_time , this ) ;
428
434
}
429
435
} ;
430
436
@@ -441,12 +447,13 @@ RedisClient.prototype.ready_check = function () {
441
447
} ;
442
448
443
449
RedisClient . prototype . send_offline_queue = function ( ) {
444
- var command_obj , buffered_writes = 0 ;
450
+ var command_obj ;
445
451
446
452
while ( command_obj = this . offline_queue . shift ( ) ) {
447
453
debug ( 'Sending offline command: ' + command_obj . command ) ;
448
- buffered_writes += ! this . send_command ( command_obj . command , command_obj . args , command_obj . callback ) ;
454
+ this . send_command ( command_obj . command , command_obj . args , command_obj . callback ) ;
449
455
}
456
+ this . drain ( ) ;
450
457
// Even though items were shifted off, Queue backing store still uses memory until next add, so just get a new Queue
451
458
this . offline_queue = new Queue ( ) ;
452
459
} ;
@@ -543,7 +550,7 @@ RedisClient.prototype.return_error = function (err) {
543
550
err . code = match [ 1 ] ;
544
551
}
545
552
546
- this . emit_drain_idle ( queue_len ) ;
553
+ this . emit_idle ( queue_len ) ;
547
554
548
555
if ( command_obj . callback ) {
549
556
command_obj . callback ( err ) ;
@@ -557,16 +564,12 @@ RedisClient.prototype.drain = function () {
557
564
this . should_buffer = false ;
558
565
} ;
559
566
560
- RedisClient . prototype . emit_drain_idle = function ( queue_len ) {
567
+ RedisClient . prototype . emit_idle = function ( queue_len ) {
561
568
if ( this . pub_sub_mode === false && queue_len === 0 ) {
562
569
// Free the queue capacity memory by using a new queue
563
570
this . command_queue = new Queue ( ) ;
564
571
this . emit ( 'idle' ) ;
565
572
}
566
-
567
- if ( this . should_buffer && queue_len <= this . command_queue_low_water ) {
568
- this . drain ( ) ;
569
- }
570
573
} ;
571
574
572
575
RedisClient . prototype . return_reply = function ( reply ) {
@@ -587,7 +590,7 @@ RedisClient.prototype.return_reply = function (reply) {
587
590
588
591
queue_len = this . command_queue . length ;
589
592
590
- this . emit_drain_idle ( queue_len ) ;
593
+ this . emit_idle ( queue_len ) ;
591
594
592
595
if ( command_obj && ! command_obj . sub_command ) {
593
596
if ( typeof command_obj . callback === 'function' ) {
@@ -640,7 +643,7 @@ RedisClient.prototype.return_reply = function (reply) {
640
643
}
641
644
/* istanbul ignore else: this is a safety check that we should not be able to trigger */
642
645
else if ( this . monitoring ) {
643
- if ( Buffer . isBuffer ( reply ) ) {
646
+ if ( typeof reply !== 'string' ) {
644
647
reply = reply . toString ( ) ;
645
648
}
646
649
// If in monitoring mode only two commands are valid ones: AUTH and MONITOR wich reply with OK
@@ -662,8 +665,8 @@ RedisClient.prototype.send_command = function (command, args, callback) {
662
665
var arg , command_obj , i , err ,
663
666
stream = this . stream ,
664
667
command_str = '' ,
665
- buffered_writes = 0 ,
666
668
buffer_args = false ,
669
+ big_data = false ,
667
670
buffer = this . options . return_buffers ;
668
671
669
672
if ( args === undefined ) {
@@ -695,7 +698,12 @@ RedisClient.prototype.send_command = function (command, args, callback) {
695
698
for ( i = 0 ; i < args . length ; i += 1 ) {
696
699
if ( Buffer . isBuffer ( args [ i ] ) ) {
697
700
buffer_args = true ;
698
- break ;
701
+ } else if ( typeof args [ i ] !== 'string' ) {
702
+ arg = String ( arg ) ;
703
+ // 30000 seemed to be a good value to switch to buffers after testing this with and checking the pros and cons
704
+ } else if ( args [ i ] . length > 30000 ) {
705
+ big_data = true ;
706
+ args [ i ] = new Buffer ( args [ i ] ) ;
699
707
}
700
708
}
701
709
if ( this . options . detect_buffers ) {
@@ -741,74 +749,53 @@ RedisClient.prototype.send_command = function (command, args, callback) {
741
749
742
750
// Always use 'Multi bulk commands', but if passed any Buffer args, then do multiple writes, one for each arg.
743
751
// This means that using Buffers in commands is going to be slower, so use Strings if you don't already have a Buffer.
744
-
745
752
command_str = '*' + ( args . length + 1 ) + '\r\n$' + command . length + '\r\n' + command + '\r\n' ;
746
753
747
- if ( ! buffer_args ) { // Build up a string and send entire command in one write
754
+ if ( ! buffer_args && ! big_data ) { // Build up a string and send entire command in one write
748
755
for ( i = 0 ; i < args . length ; i += 1 ) {
749
- arg = args [ i ] ;
750
- if ( typeof arg !== 'string' ) {
751
- arg = String ( arg ) ;
752
- }
756
+ arg = String ( args [ i ] ) ;
753
757
command_str += '$' + Buffer . byteLength ( arg ) + '\r\n' + arg + '\r\n' ;
754
758
}
755
759
debug ( 'Send ' + this . address + ' id ' + this . connection_id + ': ' + command_str ) ;
756
- buffered_writes += ! this . write ( command_str ) ;
760
+ this . write ( command_str ) ;
757
761
} else {
758
762
debug ( 'Send command (' + command_str + ') has Buffer arguments' ) ;
759
- buffered_writes += ! this . write ( command_str ) ;
763
+ this . write ( command_str ) ;
760
764
761
765
for ( i = 0 ; i < args . length ; i += 1 ) {
762
766
arg = args [ i ] ;
763
- if ( Buffer . isBuffer ( arg ) ) {
764
- if ( arg . length === 0 ) {
765
- debug ( 'send_command: using empty string for 0 length buffer' ) ;
766
- buffered_writes += ! this . write ( '$0\r\n\r\n' ) ;
767
- } else {
768
- buffered_writes += ! this . write ( '$' + arg . length + '\r\n' ) ;
769
- buffered_writes += ! this . write ( arg ) ;
770
- buffered_writes += ! this . write ( '\r\n' ) ;
771
- debug ( 'send_command: buffer send ' + arg . length + ' bytes' ) ;
772
- }
767
+ if ( ! Buffer . isBuffer ( arg ) ) {
768
+ arg = String ( arg ) ;
769
+ this . write ( '$' + Buffer . byteLength ( arg ) + '\r\n' + arg + '\r\n' ) ;
773
770
} else {
774
- if ( typeof arg !== 'string' ) {
775
- arg = String ( arg ) ;
776
- }
777
- debug ( 'send_command: string send ' + Buffer . byteLength ( arg ) + ' bytes: ' + arg ) ;
778
- buffered_writes += ! this . write ( '$' + Buffer . byteLength ( arg ) + '\r\n' + arg + '\r\n' ) ;
771
+ this . write ( '$' + arg . length + '\r\n' ) ;
772
+ this . write ( arg ) ;
773
+ this . write ( '\r\n' ) ;
779
774
}
775
+ debug ( 'send_command: buffer send ' + arg . length + ' bytes' ) ;
780
776
}
781
777
}
782
- if ( buffered_writes !== 0 || this . command_queue . length >= this . command_queue_high_water ) {
783
- debug ( 'send_command buffered_writes: ' + buffered_writes , ' should_buffer: ' + this . should_buffer ) ;
784
- this . should_buffer = true ;
785
- }
786
778
return ! this . should_buffer ;
787
779
} ;
788
780
789
781
RedisClient . prototype . write = function ( data ) {
790
- return this . stream . write ( data ) ;
791
- } ;
792
-
793
- RedisClient . prototype . writeStream = function ( data ) {
794
- var nr = 0 ;
795
-
796
782
if ( this . pipeline === 0 ) {
797
- return this . stream . write ( data ) ;
783
+ this . should_buffer = ! this . stream . write ( data ) ;
784
+ return ;
798
785
}
799
786
800
787
this . pipeline -- ;
801
788
if ( this . pipeline === 0 ) {
802
- var command ;
789
+ var command , str = '' ;
803
790
while ( command = this . pipeline_queue . shift ( ) ) {
804
- nr += ! this . stream . write ( command ) ;
791
+ str += command ;
805
792
}
806
- nr + = ! this . stream . write ( data ) ;
807
- return ! nr ;
793
+ this . should_buffer = ! this . stream . write ( str + data ) ;
794
+ return ;
808
795
}
809
796
810
797
this . pipeline_queue . push ( data ) ;
811
- return true ;
798
+ return ;
812
799
} ;
813
800
814
801
RedisClient . prototype . pub_sub_command = function ( command_obj ) {
@@ -1102,7 +1089,7 @@ Multi.prototype.exec_transaction = function (callback) {
1102
1089
this . send_command ( command , args , index , cb ) ;
1103
1090
}
1104
1091
1105
- this . _client . stream . uncork ( ) ;
1092
+ this . _client . uncork ( ) ;
1106
1093
return this . _client . send_command ( 'exec' , [ ] , function ( err , replies ) {
1107
1094
self . execute_callback ( err , replies ) ;
1108
1095
} ) ;
@@ -1210,7 +1197,7 @@ Multi.prototype.exec = Multi.prototype.EXEC = Multi.prototype.exec_batch = funct
1210
1197
this . _client . send_command ( command , args , cb ) ;
1211
1198
index ++ ;
1212
1199
}
1213
- this . _client . stream . uncork ( ) ;
1200
+ this . _client . uncork ( ) ;
1214
1201
return this . _client . should_buffer ;
1215
1202
} ;
1216
1203
0 commit comments