@@ -511,10 +511,12 @@ module Net
511
511
#
512
512
# - #greeting: The server's initial untagged response, which can indicate a
513
513
# pre-authenticated connection.
514
- # - #responses: A hash with arrays of unhandled <em>non-+nil+</em>
515
- # UntaggedResponse and ResponseCode +#data+, keyed by +#name+.
514
+ # - #responses: Yields unhandled UntaggedResponse#data and <em>non-+nil+</em>
515
+ # ResponseCode#data.
516
+ # - #clear_responses: Deletes unhandled data from #responses and returns it.
516
517
# - #add_response_handler: Add a block to be called inside the receiver thread
517
518
# with every server response.
519
+ # - #response_handlers: Returns the list of response handlers.
518
520
# - #remove_response_handler: Remove a previously added response handler.
519
521
#
520
522
#
@@ -710,22 +712,6 @@ class IMAP < Protocol
710
712
# Returns the initial greeting the server, an UntaggedResponse.
711
713
attr_reader :greeting
712
714
713
- # Returns a hash with arrays of unhandled <em>non-+nil+</em>
714
- # UntaggedResponse#data keyed by UntaggedResponse#name, and
715
- # ResponseCode#data keyed by ResponseCode#name.
716
- #
717
- # For example:
718
- #
719
- # imap.select("inbox")
720
- # p imap.responses["EXISTS"][-1]
721
- # #=> 2
722
- # p imap.responses["UIDVALIDITY"][-1]
723
- # #=> 968263756
724
- attr_reader :responses
725
-
726
- # Returns all response handlers.
727
- attr_reader :response_handlers
728
-
729
715
# Seconds to wait until a connection is opened.
730
716
# If the IMAP object cannot open a connection within this time,
731
717
# it raises a Net::OpenTimeout exception. The default value is 30 seconds.
@@ -734,8 +720,6 @@ class IMAP < Protocol
734
720
# Seconds to wait until an IDLE response is received.
735
721
attr_reader :idle_response_timeout
736
722
737
- attr_accessor :client_thread # :nodoc:
738
-
739
723
# The hostname this client connected to
740
724
attr_reader :host
741
725
@@ -768,6 +752,11 @@ class << self
768
752
alias default_ssl_port default_tls_port
769
753
end
770
754
755
+ def client_thread # :nodoc:
756
+ warn "Net::IMAP#client_thread is deprecated and will be removed soon."
757
+ @client_thread
758
+ end
759
+
771
760
# Disconnects from the server.
772
761
#
773
762
# Related: #logout
@@ -1084,11 +1073,11 @@ def login(user, password)
1084
1073
# to select a +mailbox+ so that messages in the +mailbox+ can be accessed.
1085
1074
#
1086
1075
# After you have selected a mailbox, you may retrieve the number of items in
1087
- # that mailbox from <tt>imap.responses[ "EXISTS"][-1] </tt>, and the number of
1088
- # recent messages from <tt>imap.responses[ "RECENT"][-1] </tt>. Note that
1089
- # these values can change if new messages arrive during a session or when
1090
- # existing messages are expunged; see #add_response_handler for a way to
1091
- # detect these events.
1076
+ # that mailbox from <tt>imap.responses( "EXISTS", &:last) </tt>, and the
1077
+ # number of recent messages from <tt>imap.responses( "RECENT", &:last) </tt>.
1078
+ # Note that these values can change if new messages arrive during a session
1079
+ # or when existing messages are expunged; see #add_response_handler for a
1080
+ # way to detect these events.
1092
1081
#
1093
1082
# A Net::IMAP::NoResponseError is raised if the mailbox does not
1094
1083
# exist or is for some reason non-selectable.
@@ -1954,6 +1943,104 @@ def idle_done
1954
1943
end
1955
1944
end
1956
1945
1946
+ # :call-seq:
1947
+ # responses {|hash| ...} -> block result
1948
+ # responses(type) {|array| ...} -> block result
1949
+ #
1950
+ # Yields unhandled responses and returns the result of the block.
1951
+ #
1952
+ # Unhandled responses are stored in a hash, with arrays of
1953
+ # <em>non-+nil+</em> UntaggedResponse#data keyed by UntaggedResponse#name
1954
+ # and ResponseCode#data keyed by ResponseCode#name. Call without +type+ to
1955
+ # yield the entire responses hash. Call with +type+ to yield only the array
1956
+ # of responses for that type.
1957
+ #
1958
+ # For example:
1959
+ #
1960
+ # imap.select("inbox")
1961
+ # p imap.responses("EXISTS", &:last)
1962
+ # #=> 2
1963
+ # p imap.responses("UIDVALIDITY", &:last)
1964
+ # #=> 968263756
1965
+ #
1966
+ # >>>
1967
+ # *Note:* Access to the responses hash is synchronized for thread-safety.
1968
+ # The receiver thread and response_handlers cannot process new responses
1969
+ # until the block completes. Accessing either the response hash or its
1970
+ # response type arrays outside of the block is unsafe.
1971
+ #
1972
+ # Calling without a block is unsafe and deprecated. Future releases will
1973
+ # raise ArgumentError unless a block is given.
1974
+ #
1975
+ # Previously unhandled responses are automatically cleared before entering a
1976
+ # mailbox with #select or #examine. Long-lived connections can receive many
1977
+ # unhandled server responses, which must be pruned or they will continually
1978
+ # consume more memory. Update or clear the responses hash or arrays inside
1979
+ # the block, or use #clear_responses.
1980
+ #
1981
+ # Only non-+nil+ data is stored. Many important response codes have no data
1982
+ # of their own, but are used as "tags" on the ResponseText object they are
1983
+ # attached to. ResponseText will be accessible by its response types:
1984
+ # "+OK+", "+NO+", "+BAD+", "+BYE+", or "+PREAUTH+".
1985
+ #
1986
+ # TaggedResponse#data is not saved to #responses, nor is any
1987
+ # ResponseCode#data on tagged responses. Although some command methods do
1988
+ # return the TaggedResponse directly, #add_response_handler must be used to
1989
+ # handle all response codes.
1990
+ #
1991
+ # Related: #clear_responses, #response_handlers, #greeting
1992
+ def responses ( type = nil )
1993
+ if block_given?
1994
+ synchronize { yield ( type ? @responses [ type . to_s . upcase ] : @responses ) }
1995
+ elsif type
1996
+ raise ArgumentError , "Pass a block or use #clear_responses"
1997
+ else
1998
+ # warn("DEPRECATED: pass a block or use #clear_responses", uplevel: 1)
1999
+ @responses
2000
+ end
2001
+ end
2002
+
2003
+ # :call-seq:
2004
+ # clear_responses -> hash
2005
+ # clear_responses(type) -> array
2006
+ #
2007
+ # Clears and returns the unhandled #responses hash or the unhandled
2008
+ # responses array for a single response +type+.
2009
+ #
2010
+ # Clearing responses is synchronized with other threads. The lock is
2011
+ # released before returning.
2012
+ #
2013
+ # Related: #responses, #response_handlers
2014
+ def clear_responses ( type = nil )
2015
+ synchronize {
2016
+ if type
2017
+ @responses . delete ( type ) || [ ]
2018
+ else
2019
+ @responses . dup . transform_values ( &:freeze )
2020
+ . tap { _1 . default = [ ] . freeze }
2021
+ . tap { @responses . clear }
2022
+ end
2023
+ }
2024
+ . freeze
2025
+ end
2026
+
2027
+ # Returns all response handlers, including those that are added internally
2028
+ # by commands. Each response handler will be called with every new
2029
+ # UntaggedResponse, TaggedResponse, and ContinuationRequest.
2030
+ #
2031
+ # Response handlers are called with a mutex inside the receiver thread. New
2032
+ # responses cannot be processed and commands from other threads must wait
2033
+ # until all response_handlers return. An exception will shut-down the
2034
+ # receiver thread and close the connection.
2035
+ #
2036
+ # For thread-safety, the returned array is a frozen copy of the internal
2037
+ # array.
2038
+ #
2039
+ # Related: #add_response_handler, #remove_response_handler
2040
+ def response_handlers
2041
+ synchronize { @response_handlers . clone . freeze }
2042
+ end
2043
+
1957
2044
# Adds a response handler. For example, to detect when
1958
2045
# the server sends a new EXISTS response (which normally
1959
2046
# indicates new messages being added to the mailbox),
@@ -1966,14 +2053,21 @@ def idle_done
1966
2053
# end
1967
2054
# }
1968
2055
#
2056
+ # Related: #remove_response_handler, #response_handlers
1969
2057
def add_response_handler ( handler = nil , &block )
1970
2058
raise ArgumentError , "two Procs are passed" if handler && block
1971
- @response_handlers . push ( block || handler )
2059
+ synchronize do
2060
+ @response_handlers . push ( block || handler )
2061
+ end
1972
2062
end
1973
2063
1974
2064
# Removes the response handler.
2065
+ #
2066
+ # Related: #add_response_handler, #response_handlers
1975
2067
def remove_response_handler ( handler )
1976
- @response_handlers . delete ( handler )
2068
+ synchronize do
2069
+ @response_handlers . delete ( handler )
2070
+ end
1977
2071
end
1978
2072
1979
2073
private
0 commit comments