forked from nhibernate/nhibernate-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSessionIdLoggingContext.cs
86 lines (78 loc) · 2.1 KB
/
SessionIdLoggingContext.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using System;
#if NETFX
using System.Runtime.Remoting.Messaging;
#else
using System.Threading;
#endif
namespace NHibernate.Impl
{
public class SessionIdLoggingContext : IDisposable
{
#if NETFX
private const string LogicalCallContextVariableName = "__" + nameof(SessionIdLoggingContext) + "__";
#else
private static readonly Lazy<AsyncLocal<Guid?>> _currentSessionId =
new Lazy<AsyncLocal<Guid?>>(() => new AsyncLocal<Guid?>(), true);
#endif
private readonly Guid? _oldSessionId;
private bool _hasChanged;
[Obsolete("Please use SessionIdLoggingContext.CreateOrNull instead.")]
public SessionIdLoggingContext(Guid id)
{
if (id == Guid.Empty) return;
_oldSessionId = SessionId;
if (id == _oldSessionId) return;
_hasChanged = true;
SessionId = id;
}
private SessionIdLoggingContext(Guid newId, Guid? oldId)
{
SessionId = newId;
_oldSessionId = oldId;
_hasChanged = true;
}
public static IDisposable CreateOrNull(Guid id)
{
if (id == Guid.Empty)
return null;
var oldId = SessionId;
if (oldId == id)
return null;
return new SessionIdLoggingContext(id, oldId);
}
/// <summary>
/// We always set the result to use an async local variable, on the face of it,
/// it looks like it is not a valid choice, since ASP.Net and WCF may decide to switch
/// threads on us. But, since SessionIdLoggingContext is only used inside NH calls, and since
/// NH calls are either async-await or fully synchronous, this isn't an issue for us.
/// In addition to that, attempting to match to the current context has proven to be performance hit.
/// </summary>
public static Guid? SessionId
{
get
{
#if NETFX
return (Guid?) CallContext.LogicalGetData(LogicalCallContextVariableName);
#else
return _currentSessionId.IsValueCreated ? _currentSessionId.Value.Value : null;
#endif
}
set
{
#if NETFX
CallContext.LogicalSetData(LogicalCallContextVariableName, value);
#else
_currentSessionId.Value.Value = value;
#endif
}
}
public void Dispose()
{
if (_hasChanged)
{
SessionId = _oldSessionId;
_hasChanged = false;
}
}
}
}