@@ -21,46 +21,44 @@ namespace Google.Cloud.Spanner.V1;
2121public partial class SpannerClientImpl
2222{
2323 /// <summary>
24- /// The process ID.
24+ /// The process ID. Can be set only once and before any Spanner request has been executed.
2525 /// </summary>
2626 /// <exception cref="InvalidOperationException">The process ID has already been set.</exception>
2727 internal static ulong ProcessId
2828 {
29- set => ProcessIdSource . Set ( value ) ;
30- }
31-
32- private static class ProcessIdSource
33- {
34- private static string s_value ;
35- internal static string Value
29+ set
3630 {
37- get
31+ if ( ! ProcessIdSource . TrySetProcessId ( value ) )
3832 {
39- // If not set, attempt to set it with a new random value.
40- // (It's okay if multiple threads generate a value; only the first one wins).
41- if ( s_value == null )
42- {
43- Interlocked . CompareExchange ( ref s_value , GenerateId ( ) , null ) ;
44- }
45- return s_value ;
33+ throw new InvalidOperationException ( "The Process ID was already set and cannot be overwritten now." ) ;
4634 }
4735 }
36+ }
4837
49- internal static void Set ( ulong id )
38+ private static class ProcessIdSource
39+ {
40+ private static string s_explicitvalue ;
41+ private static readonly Lazy < string > ProcessIdCache = new Lazy < string > ( ProcessIdUncached , LazyThreadSafetyMode . ExecutionAndPublication ) ;
42+
43+ internal static string Value => ProcessIdCache . Value ;
44+
45+ internal static bool TrySetProcessId ( ulong id ) =>
46+ Interlocked . CompareExchange ( ref s_explicitvalue , id . ToString ( ) , null ) != null ;
47+
48+ private static string ProcessIdUncached ( )
5049 {
51- // Atomically set the value. If it was already set (i.e. returns non-null), throw.
52- if ( Interlocked . CompareExchange ( ref s_value , id . ToString ( ) , null ) != null )
50+ // ProcessId had not been explicitly set, we need to generate one.
51+ // And it's perfectly fine that we left it set to zero,
52+ // that's enough to make it fail if someone tries to change it,
53+ // and we won't use that value anymore.
54+ if ( TrySetProcessId ( 0 ) )
5355 {
54- throw new InvalidOperationException ( "The Process ID was already set and cannot be overwritten now." ) ;
56+ var random = new Random ( ) ;
57+ var buffer = new byte [ sizeof ( ulong ) ] ;
58+ random . NextBytes ( buffer ) ;
59+ return BitConverter . ToUInt64 ( buffer , 0 ) . ToString ( ) ;
5560 }
56- }
57-
58- private static string GenerateId ( )
59- {
60- var random = new Random ( ) ;
61- var buffer = new byte [ sizeof ( ulong ) ] ;
62- random . NextBytes ( buffer ) ;
63- return BitConverter . ToUInt64 ( buffer , 0 ) . ToString ( ) ;
61+ return s_explicitvalue ;
6462 }
6563 }
6664}
0 commit comments