@@ -257,6 +257,17 @@ public long AsyncAddPublication(string channel, int streamId)
257
257
{
258
258
return _conductor . AsyncAddPublication ( channel , streamId ) ;
259
259
}
260
+
261
+ /// <summary>
262
+ /// Asynchronously remove a <seealso cref="Publication"/>.
263
+ /// </summary>
264
+ /// <param name="registrationId"> to be of the publication removed. </param>
265
+ /// <seealso cref="AsyncAddPublication(String, int)"/>
266
+ /// <seealso cref="AsyncAddExclusivePublication(String, int)"/>
267
+ public void AsyncRemovePublication ( long registrationId )
268
+ {
269
+ _conductor . RemovePublication ( registrationId ) ;
270
+ }
260
271
261
272
/// <summary>
262
273
/// Asynchronously add a <seealso cref="Publication"/> for publishing messages to subscribers from a single thread.
@@ -948,6 +959,30 @@ static Context()
948
959
/// Placeholder value to use in URIs to specify that a timestamp should be stored in the reserved value field.
949
960
/// </summary>
950
961
public const string RESERVED_OFFSET = "reserved" ;
962
+
963
+ /// <summary>
964
+ /// Property name for a fallback PrintStream based logger when it is not possible to use the error logging
965
+ /// callback. Supported values are stdout, stderr, no_op (stderr is the default).
966
+ /// </summary>
967
+ public const string FALLBACK_LOGGER_PROP_NAME = "aeron.fallback.logger" ;
968
+
969
+ /// <summary>
970
+ /// Get the current fallback logger based on the supplied property.
971
+ /// </summary>
972
+ /// <returns> the configured PrintStream. </returns>
973
+ public static TextWriter FallbackLogger ( )
974
+ {
975
+ string fallbackLoggerName = Config . GetProperty ( FALLBACK_LOGGER_PROP_NAME , "stderr" ) ;
976
+ switch ( fallbackLoggerName )
977
+ {
978
+ case "stdout" :
979
+ return Console . Out ;
980
+
981
+ case "stderr" :
982
+ default :
983
+ return Console . Error ;
984
+ }
985
+ }
951
986
952
987
/// <summary>
953
988
/// Get the default directory name to be used if <seealso cref="AeronDirectoryName(String)"/> is not set. This will take
@@ -1999,7 +2034,7 @@ public MappedByteBuffer MapExistingCncFile(Action<string> logProgress)
1999
2034
{
2000
2035
FileInfo cncFile = new FileInfo ( Path . Combine ( _aeronDirectory . FullName , CncFileDescriptor . CNC_FILE ) ) ;
2001
2036
2002
- if ( cncFile . Exists && cncFile . Length > 0 )
2037
+ if ( cncFile . Exists && cncFile . Length > CncFileDescriptor . END_OF_METADATA_OFFSET )
2003
2038
{
2004
2039
if ( null != logProgress )
2005
2040
{
@@ -2023,7 +2058,7 @@ public static bool IsDriverActive(DirectoryInfo directory, long driverTimeoutMs,
2023
2058
{
2024
2059
FileInfo cncFile = new FileInfo ( Path . Combine ( directory . FullName , CncFileDescriptor . CNC_FILE ) ) ;
2025
2060
2026
- if ( cncFile . Exists && cncFile . Length > 0 )
2061
+ if ( cncFile . Exists && cncFile . Length > CncFileDescriptor . END_OF_METADATA_OFFSET )
2027
2062
{
2028
2063
logger ( "INFO: Aeron CnC file " + cncFile + " exists" ) ;
2029
2064
@@ -2120,23 +2155,26 @@ public static bool RequestDriverTermination(
2120
2155
{
2121
2156
FileInfo cncFile = new FileInfo ( Path . Combine ( directory . FullName , CncFileDescriptor . CNC_FILE ) ) ;
2122
2157
2123
- if ( cncFile . Exists && cncFile . Length > 0 )
2158
+ if ( cncFile . Exists && cncFile . Length > CncFileDescriptor . END_OF_METADATA_OFFSET )
2124
2159
{
2125
2160
var cncByteBuffer = IoUtil . MapExistingFile ( cncFile , "CnC file" ) ;
2126
2161
try
2127
2162
{
2128
2163
UnsafeBuffer cncMetaDataBuffer = CncFileDescriptor . CreateMetaDataBuffer ( cncByteBuffer ) ;
2129
2164
int cncVersion = cncMetaDataBuffer . GetIntVolatile ( CncFileDescriptor . CncVersionOffset ( 0 ) ) ;
2130
2165
2131
- CncFileDescriptor . CheckVersion ( cncVersion ) ;
2166
+ if ( cncVersion > 0 )
2167
+ {
2168
+ CncFileDescriptor . CheckVersion ( cncVersion ) ;
2132
2169
2133
- ManyToOneRingBuffer toDriverBuffer =
2134
- new ManyToOneRingBuffer (
2135
- CncFileDescriptor . CreateToDriverBuffer ( cncByteBuffer , cncMetaDataBuffer ) ) ;
2136
- long clientId = toDriverBuffer . NextCorrelationId ( ) ;
2137
- DriverProxy driverProxy = new DriverProxy ( toDriverBuffer , clientId ) ;
2170
+ ManyToOneRingBuffer toDriverBuffer =
2171
+ new ManyToOneRingBuffer (
2172
+ CncFileDescriptor . CreateToDriverBuffer ( cncByteBuffer , cncMetaDataBuffer ) ) ;
2173
+ long clientId = toDriverBuffer . NextCorrelationId ( ) ;
2174
+ DriverProxy driverProxy = new DriverProxy ( toDriverBuffer , clientId ) ;
2138
2175
2139
- return driverProxy . TerminateDriver ( tokenBuffer , tokenOffset , tokenLength ) ;
2176
+ return driverProxy . TerminateDriver ( tokenBuffer , tokenOffset , tokenLength ) ;
2177
+ }
2140
2178
}
2141
2179
finally
2142
2180
{
@@ -2191,7 +2229,7 @@ public int SaveErrorLog(StreamWriter writer, MappedByteBuffer cncByteBuffer)
2191
2229
public static int PrintErrorLog ( IAtomicBuffer errorBuffer , TextWriter @out )
2192
2230
{
2193
2231
int distinctErrorCount = 0 ;
2194
- if ( ErrorLogReader . HasErrors ( errorBuffer ) )
2232
+ if ( errorBuffer . Capacity > 0 && ErrorLogReader . HasErrors ( errorBuffer ) )
2195
2233
{
2196
2234
void ErrorConsumer ( int count , long firstTimestamp , long lastTimestamp , string ex )
2197
2235
=> @out . WriteLine (
0 commit comments