You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ibatis.apache.org by "Gilles Bayon (JIRA)" <ib...@incubator.apache.org> on 2008/10/22 19:57:44 UTC

[jira] Closed: (IBATISNET-285) flushInterval ist calculated wrong

     [ https://issues.apache.org/jira/browse/IBATISNET-285?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Gilles Bayon closed IBATISNET-285.
----------------------------------

       Resolution: Fixed
    Fix Version/s: DataMapper 1.6.2
         Assignee: Gilles Bayon

in svn

> flushInterval ist calculated wrong
> ----------------------------------
>
>                 Key: IBATISNET-285
>                 URL: https://issues.apache.org/jira/browse/IBATISNET-285
>             Project: iBatis for .NET
>          Issue Type: Bug
>          Components: DataMapper
>    Affects Versions: DataMapper 1.6.1
>            Reporter: Stefan Hoehn
>            Assignee: Gilles Bayon
>             Fix For: DataMapper 1.6.2
>
>
> We noticed that if the flushInterval like in 
> 	<cacheModels>
> 		<cacheModel id="NavigationCache" implementation="MEMORY" readOnly="false" serialize="true">
> 			<!-- User bekommen Kopien aus dem Cache -->
> 			<flushInterval minutes="1"/>
> 			<property name="Type" value="STRONG"/>
> 		</cacheModel>		
> 	</cacheModels>
> is provided it results in a completely wrong number. There are two bugs that lead to a wrong result. The first one is very minor because it decreases the given interval time by about ten milliseconds. The second one is more severe: It results in a somewhat twice the time of the cache interval given in the configuration.
> Bug #1: The negative default value is being added
> in FlushInterval.cs you find the following code:
>                 private long _interval = CacheModel.NO_FLUSH_INTERVAL;   // equals  -99999
>                 //................
> 		public void Initialize()
> 		{
> 			if (_milliseconds != 0) 
> 			{
> 				_interval += (_milliseconds * TimeSpan.TicksPerMillisecond) ;
> 			}
> 			if (_seconds != 0) 
> 			{
> 				_interval += (_seconds * TimeSpan.TicksPerSecond) ;
> 			}
> 			if (_minutes != 0) 
> 			{
> 				_interval += (_minutes * TimeSpan.TicksPerMinute) ;
> 			}
> 			if (_hours != 0) 
> 			{
> 				_interval += (_hours * TimeSpan.TicksPerHour) ;
> 			}
> 			if (_interval == 0)
> 			{
> 				_interval = CacheModel.NO_FLUSH_INTERVAL;
> 			}         
>            }
>            The result in our case is -99999+600000000 = 599900001.
>            Granted that the effect is only about 10 Milliseconds but still, it is wrong :-)
> Bug #2: FlushInterval.initialize() is called twice during initialization
> If you follow the Deserialization of the DomSqlMapBuilder in ConfigureSQLMap()  you will find the following code,which calls CacheModelDeSerializer.Deserialize():
> #region Load CacheModels
> 			if (_configScope.IsCacheModelsEnabled)
> 			{
> 				CacheModel cacheModel;
> 				foreach (XmlNode xmlNode in _configScope.SqlMapDocument.SelectNodes( ApplyMappingNamespacePrefix(XML_CACHE_MODEL), _configScope.XmlNamespaceManager))
> 				{
> 					cacheModel = CacheModelDeSerializer.Deserialize(xmlNode, _configScope);
>                     cacheModel.Id = _configScope.ApplyNamespace(cacheModel.Id);
> 					// Attach ExecuteEventHandler
> 					foreach(XmlNode flushOn in xmlNode.SelectNodes( ApplyMappingNamespacePrefix(XML_FLUSH_ON_EXECUTE), _configScope.XmlNamespaceManager  ))
> 					{
> 						string statementName = flushOn.Attributes["statement"].Value;
> 						if (_configScope.UseStatementNamespaces)
> 						{
>                             statementName = _configScope.ApplyNamespace(statementName); 
> 						}
> 						// delay registering statements to cache model until all sqlMap files have been processed
> 						IList statementNames = (IList)_configScope.CacheModelFlushOnExecuteStatements[cacheModel.Id];
> 						if (statementNames == null)
> 						{
> 							statementNames = new ArrayList();
> 						}
> 						statementNames.Add(statementName);
> 						_configScope.CacheModelFlushOnExecuteStatements[cacheModel.Id] = statementNames;
> 					}
> 					// Get Properties
> 					foreach(XmlNode propertie in xmlNode.SelectNodes( ApplyMappingNamespacePrefix(XML_PROPERTY), _configScope.XmlNamespaceManager))
> 					{
> 						string name = propertie.Attributes["name"].Value;
> 						string value = propertie.Attributes["value"].Value;
> 					
> 						cacheModel.AddProperty(name, value);
> 					}
> 					cacheModel.Initialize();
> 					_configScope.SqlMapper.AddCache( cacheModel );
> 				}
> 			}
> The issue is that CacheModelDeSerializer.Deserialize(xmlNode, _configScope);  has the following implementation
> int count = node.ChildNodes.Count;
> 			for(int i=0;i<count;i++)
> 			{
> 				if (node.ChildNodes[i].LocalName=="flushInterval")
> 				{
> 					FlushInterval flush = new FlushInterval();
> 					NameValueCollection props = NodeUtils.ParseAttributes(node.ChildNodes[i], configScope.Properties);
> 					flush.Hours = NodeUtils.GetIntAttribute(props, "hours", 0);
> 					flush.Milliseconds = NodeUtils.GetIntAttribute(props, "milliseconds", 0);
> 					flush.Minutes = NodeUtils.GetIntAttribute(props, "minutes", 0);
> 					flush.Seconds = NodeUtils.GetIntAttribute(props, "seconds", 0);
> 					flush.Initialize();
> 					
> 					model.FlushInterval = flush;
> 				}
> 			}
> and therefore calls flush.Initialize() as soon as it find an property "flushInterval". So far so good as this results in getting the above number: 599900001
> However, back again in ConfigureSQLMap  further down it calls cacheModel.Initialize(); which in turn calls _flushInterval.Initialize(); again adding another 600000000 resulting in 1199900001, almost twice of what we wanted. 
> The initialization-Method must no be called twice.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.