1
+ //-----------------------------------------------------------------------
2
+ // <copyright file="StashCapacitySpecs.cs" company="Akka.NET Project">
3
+ // Copyright (C) 2009-2023 Lightbend Inc. <http://www.lightbend.com>
4
+ // Copyright (C) 2013-2023 .NET Foundation <https://github.com/akkadotnet/akka.net>
5
+ // </copyright>
6
+ //-----------------------------------------------------------------------
7
+
8
+ using System ;
9
+ using System . Threading . Tasks ;
10
+ using Akka . Actor ;
11
+ using Akka . Configuration ;
12
+ using Akka . TestKit ;
13
+ using Xunit ;
14
+ using Xunit . Abstractions ;
15
+ using FluentAssertions ;
16
+
17
+ namespace Akka . Tests . Actor . Stash ;
18
+
19
+ public class StashCapacitySpecs : AkkaSpec
20
+ {
21
+ public StashCapacitySpecs ( ITestOutputHelper output ) : base ( Config . Empty , output : output )
22
+ {
23
+
24
+ }
25
+
26
+ [ Fact ]
27
+ public async Task ShouldGetAccurateStashReadingForUnboundedStash ( )
28
+ {
29
+ var stashActor = Sys . ActorOf ( Props . Create ( ( ) => new StashActor ( ) ) ) ;
30
+ stashActor . Tell ( new StashActor . StashMessage ( "1" ) ) ;
31
+ stashActor . Tell ( new StashActor . StashMessage ( "2" ) ) ;
32
+ stashActor . Tell ( StashActor . GetStashReadout . Instance ) ;
33
+ var readout1 = await ExpectMsgAsync < StashActor . StashReadout > ( ) ;
34
+ readout1 . Capacity . Should ( ) . Be ( - 1 ) ; // unbounded stash returns -1 for capacity
35
+ readout1 . Size . Should ( ) . Be ( 2 ) ;
36
+ readout1 . IsEmpty . Should ( ) . BeFalse ( ) ;
37
+ readout1 . IsFull . Should ( ) . BeFalse ( ) ;
38
+
39
+ stashActor . Tell ( StashActor . UnstashMessage . Instance ) ;
40
+ stashActor . Tell ( StashActor . GetStashReadout . Instance ) ;
41
+ var readout2 = await ExpectMsgAsync < StashActor . StashReadout > ( ) ;
42
+ readout2 . Capacity . Should ( ) . Be ( - 1 ) ;
43
+ readout2 . Size . Should ( ) . Be ( 1 ) ;
44
+ readout2 . IsEmpty . Should ( ) . BeFalse ( ) ;
45
+ readout2 . IsFull . Should ( ) . BeFalse ( ) ;
46
+
47
+ stashActor . Tell ( StashActor . UnstashMessage . Instance ) ;
48
+ stashActor . Tell ( StashActor . GetStashReadout . Instance ) ;
49
+ var readout3 = await ExpectMsgAsync < StashActor . StashReadout > ( ) ;
50
+ readout3 . Capacity . Should ( ) . Be ( - 1 ) ;
51
+ readout3 . Size . Should ( ) . Be ( 0 ) ;
52
+ readout3 . IsEmpty . Should ( ) . BeTrue ( ) ;
53
+ readout3 . IsFull . Should ( ) . BeFalse ( ) ;
54
+ }
55
+
56
+ private class StashActor : UntypedActorWithStash
57
+ {
58
+ public class StashMessage
59
+ {
60
+ public StashMessage ( string message )
61
+ {
62
+ Message = message ;
63
+ }
64
+
65
+ public string Message { get ; }
66
+ }
67
+
68
+ public class UnstashMessage
69
+ {
70
+ private UnstashMessage ( )
71
+ {
72
+
73
+ }
74
+ public static readonly UnstashMessage Instance = new ( ) ;
75
+ }
76
+
77
+ public class GetStashReadout
78
+ {
79
+ private GetStashReadout ( )
80
+ {
81
+
82
+ }
83
+ public static readonly GetStashReadout Instance = new ( ) ;
84
+ }
85
+
86
+ public class StashReadout
87
+ {
88
+ public StashReadout ( int capacity , int size , bool isEmpty , bool isFull )
89
+ {
90
+ Capacity = capacity ;
91
+ Size = size ;
92
+ IsEmpty = isEmpty ;
93
+ IsFull = isFull ;
94
+ }
95
+
96
+ public int Capacity { get ; }
97
+ public int Size { get ; }
98
+
99
+ public bool IsEmpty { get ; }
100
+
101
+ public bool IsFull { get ; }
102
+ }
103
+
104
+ protected override void OnReceive ( object message )
105
+ {
106
+ switch ( message )
107
+ {
108
+ case StashMessage msg :
109
+ Stash . Stash ( ) ;
110
+ break ;
111
+ case UnstashMessage _:
112
+ Stash . Unstash ( ) ;
113
+ Context . Become ( Unstashing ) ; // switch behaviors so we're not stuck in stash loop
114
+ break ;
115
+ case GetStashReadout _:
116
+ Sender . Tell ( new StashReadout ( Stash . Capacity , Stash . Count , Stash . IsEmpty , Stash . IsFull ) ) ;
117
+ break ;
118
+ default :
119
+ Unhandled ( message ) ;
120
+ break ;
121
+ }
122
+ }
123
+
124
+ private void Unstashing ( object message )
125
+ {
126
+ switch ( message )
127
+ {
128
+ case StashMessage msg : // do nothing
129
+ break ;
130
+ case UnstashMessage when Stash . NonEmpty :
131
+ Stash . Unstash ( ) ;
132
+ break ;
133
+ case UnstashMessage _: // when the stash is empty, go back to stashing
134
+ Context . Become ( OnReceive ) ;
135
+ break ;
136
+ case GetStashReadout _:
137
+ Sender . Tell ( new StashReadout ( Stash . Capacity , Stash . Count , Stash . IsEmpty , Stash . IsFull ) ) ;
138
+ break ;
139
+ default :
140
+ Unhandled ( message ) ;
141
+ break ;
142
+ }
143
+ }
144
+ }
145
+ }
0 commit comments