@@ -870,6 +870,159 @@ def sleep_forever
870870 end
871871 end
872872
873+ with "#wait_all" do
874+ it "will wait on all child tasks to complete" do
875+ results = [ ]
876+
877+ reactor . run do |parent |
878+ child1 = parent . async do |child |
879+ child . yield
880+ results << :child1
881+ end
882+
883+ child2 = parent . async do |child |
884+ child . yield
885+ results << :child2
886+ end
887+
888+ parent . wait_all
889+ results << :parent
890+ end
891+
892+ expect ( results ) . to be == [ :child1 , :child2 , :parent ]
893+ end
894+
895+ it "will wait recursively on nested child tasks" do
896+ results = [ ]
897+
898+ reactor . run do |parent |
899+ child = parent . async do |child |
900+ grandchild = child . async do |grandchild |
901+ grandchild . yield
902+ results << :grandchild
903+ end
904+
905+ child . yield
906+ results << :child
907+ end
908+
909+ parent . wait_all
910+ results << :parent
911+ end
912+
913+ expect ( results ) . to be == [ :grandchild , :child , :parent ]
914+ end
915+
916+ it "will skip transient tasks" do
917+ results = [ ]
918+
919+ reactor . run do |parent |
920+ child = parent . async do |child |
921+ child . yield
922+ results << :child
923+ end
924+
925+ transient = parent . async ( transient : true ) do
926+ sleep ( 0.1 )
927+ results << :transient
928+ end
929+
930+ parent . wait_all
931+ results << :parent
932+ end
933+
934+ # Transient task should not have completed
935+ expect ( results ) . to be == [ :child , :parent ]
936+ end
937+
938+ it "will handle tasks with no children" do
939+ reactor . run do |parent |
940+ result = parent . wait_all
941+ expect ( result ) . to be_nil
942+ end
943+ end
944+
945+ it "will wait on multiple levels of nesting" do
946+ results = [ ]
947+
948+ reactor . run do |parent |
949+ child1 = parent . async do |child |
950+ grandchild1 = child . async do |grandchild |
951+ grandchild . yield
952+ results << :grandchild1
953+ end
954+ child . yield
955+ results << :child1
956+ end
957+
958+ child2 = parent . async do |child |
959+ grandchild2 = child . async do |grandchild |
960+ grandchild . yield
961+ results << :grandchild2
962+ end
963+ child . yield
964+ results << :child2
965+ end
966+
967+ parent . wait_all
968+ results << :parent
969+ end
970+
971+ # All tasks should complete in order
972+ expect ( results ) . to be ( :include? , :grandchild1 )
973+ expect ( results ) . to be ( :include? , :grandchild2 )
974+ expect ( results ) . to be ( :include? , :child1 )
975+ expect ( results ) . to be ( :include? , :child2 )
976+ expect ( results . last ) . to be == :parent
977+ end
978+
979+ it "returns nil when called from within the task" do
980+ reactor . run do |parent |
981+ child = parent . async do |child |
982+ child . yield
983+ end
984+
985+ result = parent . wait_all
986+ expect ( result ) . to be_nil
987+ end
988+ end
989+
990+ it "returns the task result when called from outside" do
991+ parent = reactor . async do |parent |
992+ child = parent . async do |child |
993+ child . yield
994+ end
995+ :result
996+ end
997+
998+ reactor . run
999+
1000+ result = parent . wait_all
1001+ expect ( result ) . to be == :result
1002+ end
1003+
1004+ it "will propagate exceptions from child tasks" do
1005+ failed_child = nil
1006+
1007+ reactor . run do |parent |
1008+ failed_child = parent . async ( finished : false ) do |child |
1009+ child . yield
1010+ raise RuntimeError , "child task failed"
1011+ end
1012+
1013+ # Wait for the failed child to fail first
1014+ reactor . run
1015+
1016+ expect ( failed_child ) . to be ( :finished? )
1017+
1018+ # wait_all should propagate the exception when it calls wait on the failed child
1019+ expect do
1020+ parent . wait_all
1021+ end . to raise_exception ( RuntimeError , message : be =~ /child task failed/ )
1022+ end
1023+ end
1024+ end
1025+
8731026 with "#result" do
8741027 it "does not raise exception" do
8751028 task = reactor . async do |task |
0 commit comments