Wednesday, October 12, 2005

1341.aspx

How to add a Subscribe with Google Reader link to your blog

I have played around with Google Reader lately. I wanted to add a "subscribe with Google Reader" link to my blogs so I created a basic Google Reader subscription generator. Just enter the complete URL of you RSS feed and it generates the Google Reader subscription url:




I generated the "Sub | Google" button using the Button Maker by Adam Kalsey


Add the following to /blog/Skins/your skin/Controls/MyLinks.ascx if you have .TEXT



<asp:HyperLink


    ImageUrl="~/images/SubGoogle.png"


    Runat="server"


    NavigateUrl="Google Reader Subscription URL"


    ID="GoogleReader">


    Google Reader


</asp:HyperLink>


Here is the complete source code for the Google Reader subscription generator:


<% Option Explicit


Dim blogURL


dim googleURL


%>


<html>


      <body>


      <h1>Google Reader subscription generator</h1>


      <%


      blogURL = Request("BlogUrl")


      if blogURL <> "" then


            googleURL = "http://www.google.com/reader/preview/" & _


                        Server.URLEncode(blogURL) & "/feed/" & blogURL


           


            %>


            The <a href="http://reader.google.com/">Google Reader</a>


            subscription url for <b><%=blogURL%> is:</b><br/>


            <textarea cols="75" rows="2"><%=googleURL%></textarea>


            <br/><br/>


            Example: <a href="<%=googleURL%>">


            <img src="http://text2blogger.appspot.com/static/egilh/Images/subGoogle.png"></a>


            <%


      else


      %>


      <p>


      Enter your entire RSS url in the field below to calculate the


<a href="http://reader.google.com/">Google Reader</a>


subscription url.<br/>


      Example: http://www.egilh.com/blog/Rss.aspx


      </p>


      <form action="SubGoogleReader.asp">


      Blog RSS Feed <input type="text" name="BlogUrl" size="50"/><br/>


      <input type="submit" value="Calculate URL"/>


      </form>


      <%


      end if


      %>


      </body>


</html>

1335.aspx

Quake 3 Arena source code released

The full source code for Quake III Arena has been released under GPL. The 24MB package (when uncompressed)  comes with everything you need:



  • Quake III Arena source code ( renderer, game code, OS layer etc. )

  • Bot routes compiler source code

  • Retargetable C compiler ( produces assembly to be turned into qvm bytecode by q3asm )

  • Assembly to qvm bytecode compiler

  • Map compiler ( .map -> .bsp ) - this is the version that comes with Q3Radiant 200f

  • Q3Radiant map editor build 200f ( common/ and libs/ are support dirs for radiant )

Check the internet for spinof projects that tues the build environment and code for the various supported platforms: Windows, GNU/Linux and Mac.


I built it without problems using Visual Studio .NET 2003. The world of first person shooters has certainly moved on since I had a look at the graphics behind Caste Wolfenstein.


The source code for the older Quake versions can be downloaded from the idsoftware technology downloads site

1334.aspx

Linus on development: a spec is close to useless

Interesting point of view by Linus;



"A 'spec' is close to useless. I have _never_ seen a spec that was both big enough to be useful _and_ accurate.


And I have seen _lots_ of total crap work that was based on specs. It's _the_ single worst way to write software, because it by definition means that the software was written to match theory, not reality.


Looks like Linux is heading for total anarchy as well as for extinction...

Tuesday, October 11, 2005

1331.aspx

How to recycle com+ applications with high call times using .NET

Windows 2003 introduces a new RecycleApplicationInstances method in the COM+ Admin API. It allows transparent recycling of COM+ applications as existing requests are allowed to finish while new requests are routed to a new application instance. A lot better than the ShutDownApplication in Win2k which shuts down the process directly and returns an error to the calling client.


Win2k3 offers several recycling policies in the "Pooling & Recycling" tab of COM+ applications:



  • Lifetime limit: The application runs max X minutes before it is recycled

  • Memory Limit: The application is recycled if it uses more than X Kilo Bytes of memory. A life saver if you have third party C++ components that leak  memory

  • Call Limit: Max number of calls before the application is recycled

  • Activation Limit: Max number of object activations before the application is recycled

But a very useful limit is missing: max call time. There is no way to tell COM+ to recycle the application if an object blocks for some reason and gives very high call times.Using the egilh.comtracker you an roll your own max call time manager using .NET.


The code below loads the XML returned by egilh.comtracker in a XmlDom and checks the responseTimes. It uses the RecycleApplicationInstances COM+ API to shut down the application if the call time is higher than the configured MAX_CALL_TIME and there are objects in call.


XML returned by egilh.comtracker


<applications>


      <application>


      <guid>{98CDBB6E-3CAF-46F2-ABE6-EABECD6AA4EB}</guid>


      <ID>10</ID>


      <processID>1792</processID>


      <statistics>


            <callsPerSecond>0</callsPerSecond>


            <totalCalls>0</totalCalls>


            <totalClasses>1</totalClasses>


            <totalInstances>1</totalInstances>


      </statistics>


      <classes>


            <class>


                  <progID>Test.Sleep.1</progID>


                  <bound>1</bound>


                  <inCall>0</inCall>


                  <pooled>-1</pooled>


                  <references>1</references>


                  <responseTime>120</responseTime>


                  <callsCompleted>0</callsCompleted>


                  <callsFailed>0</callsFailed>


            </class>


      </classes>


      </application>


</applications>



Code for recycling applications with high call times


/// <summary>


/// Check the COM+ Call times, recycling applications with


/// components that have high call times


/// </summary>


private void checkComCallTimes()


{


      const int MAX_CALL_TIME = 10000; // Max call time in miliseconds


      const int RECYCLE_REASON = 408;  // The reason for the recyle. Any number is OK


 


      // Get the call statistics


      EGILHCOMTRACKERLib.ComTrackerClass comTracker = new EGILHCOMTRACKERLib.ComTrackerClass();


      string statistics = comTracker.getStatistics();


 


      // Load the statistics in a DOM and loop on the call times


      XmlDocument xmlDoc = new XmlDocument();


      xmlDoc.LoadXml(statistics);


      foreach (XmlNode node in xmlDoc.SelectNodes("//class"))


      {


            // Get class info


            string className = node.SelectSingleNode("progID").InnerText.ToLower();


            int inCall = System.Convert.ToInt32(node.SelectSingleNode("inCall").InnerText);


            long responseTime = System.Convert.ToInt64(node.SelectSingleNode("responseTime").InnerText);


 


            // Recycle if objects are in call and the call time is too high


            if (inCall > 0 && responseTime > MAX_CALL_TIME)


            {                                                                      


                  // get application PID from ../../


                  XmlNode appNode = node.ParentNode.ParentNode;


                  recycleApplication(System.Convert.ToInt32(appNode.SelectSingleNode("processID").InnerText),


                                                RECYCLE_REASON);


           


            }


      }


 


}


 


/// <summary>


/// Recycle a COM+ application instance given the process ID


/// </summary>


/// <param name="processID">Application instance process ID</param>


/// <remarks>Only works on Win2k3 and WinXP. You have to catch


/// various com+ exceptions like "The application has already been recycled"


/// and "The specified application is not longer running"</remarks>


void recycleApplication(int processID, int reason)


{


      COMAdmin.COMAdminCatalogClass adminCatalog = new COMAdmin.COMAdminCatalogClass();


 


      // Get instance guid from process id


      object instanceGUID = adminCatalog.GetApplicationInstanceIDFromProcessID(processID);


 


      // Wrap it in a single element array


      object [] applications = new object[1];                    


      applications[0] = instanceGUID;


      object recycleObject = (object) applications;


 


      // Pass reference with list of objects to recycle to RecylceApplicationInstances


      adminCatalog.RecycleApplicationInstances(ref recycleObject, reason);                                       


}


 
The API is difficult to use from VBScript as it requires a Variant pointer to a Variant array that contains the list of application instances to use. The code above only works on Windows 2003. Use the VB Script in How to shut down COM+ applications with high call times with VB and VBScript if you use Windows 2000.

1328.aspx

How to shut down COM+ applications with high call times with VB and VBScript

I posted earlier this year on How to get COM+ call times from VB and VBScript mentioning that it is possible to automatically shut down/recycle components with high call times using the COM+ Admin API. With VBScipt it is very  easy. The script below can be used from VB, VBScript or even an ASP page.


It uses the egilh.comtracker to get the COM+ call times in XML:


<applications>


      <application>


      <guid>{98CDBB6E-3CAF-46F2-ABE6-EABECD6AA4EB}</guid>


      <ID>10</ID>


      <processID>1792</processID>


      <statistics>


            <callsPerSecond>0</callsPerSecond>


            <totalCalls>0</totalCalls>


            <totalClasses>1</totalClasses>


            <totalInstances>1</totalInstances>


      </statistics>


      <classes>


            <class>


                  <progID>Test.Sleep.1</progID>


                  <bound>1</bound>


                  <inCall>0</inCall>


                  <pooled>-1</pooled>


                  <references>1</references>


                  <responseTime>120</responseTime>


                  <callsCompleted>0</callsCompleted>


                  <callsFailed>0</callsFailed>


            </class>


      </classes>


      </application>


</applications>


It loads the XML in a DOM using MSXML 3.0 and checks the responseTimes. It uses the COM+ Admin API to shut down the application if the call time is higher than the configured MAX_CALL_TIME and there are objects in call. The ShutDownApplication method works on Windows 2000 as well as Windows 2003. It has the same "brutal" effect as right clicking a COM+ application and selecting "shut down"; clients currently in call will get a COM+ error. With Windows 2003 it is possible to use recycling which routes new request to a new application instance but lets existing calls finish.


Option Explicit


 


Const MAX_CALL_TIME = 10000  'Max allowed call time in miliseconds


Const CHECK_INTERVAL = 5000  'How often we should check the call times


Const RECYCLE_REASON = 408  'The reason for the recyle. Any number is OK


 


 


'Never ending main loop that monitors the call time


Do While True


    checkCallTimes


    WScript.Sleep(CHECK_INTERVAL)


Loop


 


Private Sub checkCallTimes()


'**


'Purpose: Check the call times and shut down applications that have too high call times


    Dim oTracker 'As Object


    Dim sResult 'As String


    Dim oDOM 'As DOMDocument30


    Dim oNode 'As MSXML2.IXMLDOMNode


    Dim sProgID 'As String


    Dim lResponseTime 'As Long


    Dim lInCall 'As Long


    Dim oApp 'As MSXML2.IXMLDOMNode


    Dim bHighCallTimes 'As Boolean


 


     'Get the com+ call times


    oTracker = CreateObject("egilh.ComTracker")


    sResult = oTracker.getStatistics()


    oTracker = Nothing


 


    bHighCallTimes = False


 


    'Check call times


    oDOM = CreateObject("MSXML2.DomDocument.3.0")


    oDOM.loadXML(sResult)


    For Each oNode In oDOM.selectNodes("/applications/application/classes/class")


        lInCall = CLng(oNode.selectSingleNode("inCall").Text)


        lResponseTime = CLng(oNode.selectSingleNode("responseTime").Text)


 


        ' Check if we should recycle


        If lResponseTime > MAX_CALL_TIME And lInCall > 0 Then


            'Log that we are recycling


            sProgID = oNode.selectSingleNode("progID").Text


            WScript.Echo(Now() & " Shutting down '" & sProgID & _


                              "' because of high call time: " & lResponseTime)


 


            'We shut down the parent process: ../../processID


            oApp = oNode.parentNode.parentNode


            shutDownApplication(oApp.selectSingleNode("guid").Text)


            bHighCallTimes = True


        End If


    Next


 


    If Not bHighCallTimes Then WSCript.Echo(Now() & " Call Times OK")


End Sub


 


 


Private Sub shutDownApplication(ByVal appGuid)


'**


'Purpose: Shut down an application


'Description: Shuts down a com+ application identified by its guid.


Dim adminCatalog 'As COMAdmin.COMAdminCatalog


Dim appInstanceGUID 'As Object


 


    adminCatalog = CreateObject("COMAdmin.COMAdminCatalog")


 


    'ShutdownApplicationInstances


    adminCatalog.shutDownApplication(appGuid)


 


    adminCatalog = Nothing


End Sub

Tuesday, October 4, 2005

1324.aspx

Electronic Frontier Foundation (EFF) turns 15

EFF turns 15 this year and I got my Electronic Frontier Foundation (EFF)15th Anniversary membership t-shirt today.


Front:



 


Back:



 


I have supported EFF  for several years and hope you will to if you can spare a few bucks:



From the Internet to the iPod, technologies of freedom are transforming our society and empowering us as speakers, citizens, creators, and consumers. These technologies are increasingly under attack, and the Electronic Frontier Foundation (EFF) is the first line of defense, protecting our civil liberties in the networked world. EFF broke new ground when it was founded in 1990—well before the Internet was on most people's radar—and continues to confront cutting-edge issues defending free speech, privacy, innovation, and consumer rights today. From the beginning, EFF has championed the public interest in every critical battle affecting digital rights.


Blending the expertise of lawyers, policy analysts, activists, and technologists, EFF achieves significant victories on behalf of consumers and the general public. EFF fights for freedom primarily in the courts, bringing and defending lawsuits even when that means taking on the US government or large corporations. By mobilizing more than 50,000 concerned citizens through our Action Center, EFF beats back bad legislation. In addition to advising policymakers, EFF educates the press and public. Sometimes just defending technologies isn't enough, so EFF also helps fund and build freedom-enhancing inventions.


EFF is a donor-funded nonprofit and depends on your support to continue successfully defending your digital rights. Litigation is particularly expensive; because two-thirds of our budget comes from individual donors, every contribution is critical to helping EFF fight —and win—more cases.


especially if you are a blogger

Thursday, September 29, 2005

1321.aspx

Microsoft wants a faster JBoss on Windows Server

I do not know how much effort Microsoft will put into this; but I believe it is great news: Microsoft, JBoss Unveil Interoperability Pact 



On Tuesday, Microsoft and JBoss announced that they are looking at ways to enhance interoperability between the Windows Server and the JBoss Enterprise Middleware System (JEMS). Microsoft also said it plans to bolster support for JBoss in the Windows Server.

The companies’ technology engagement will include "technical assistance and guidance" designed to optimize the performance of JBoss on Microsoft's Active Directory integrated sign-on and federated identity capabilities and of JBoss' Hibernate object/relational mapping tool and Enterprise JavaBeans 3.0 on Microsoft’s SQL Server, according to Microsoft. The two software vendors also aim to better collaborate on Web services connectivity using the WS* standards endorsed by Microsoft and to develop a JBoss Management Pack for the Microsoft Operations Manager management platform.


That Microsoft wants JBoss to run on Windows Server instead of on Linux should be no surprise to anyone. I am glad to see that they will "better collaborate on Web services connectivity using the WS*". SOAP and Web Services are built on standards but anyone who have tried to transfer complex objects/structures between different WS vendors/platform knows that it' is far from easy. I usually end up using the method from last millennium; return a basic string that contains XML. Not the fastest and most elegant method but it works with "everything".


Wouldn't it be great if you could pass objects and collections between Java and .NET?