head	1.19;
access;
symbols
	TIGRIS_1_1_0RC2:1.8.2.12
	TIGRIS_1_1_0RC1:1.8.2.12
	TIGRIS_1_1:1.8.2.12.0.2
	TIGRIS_1_0_8:1.8.2.12
	TIGRIS_1_0_8RC3:1.8.2.12
	TIGRIS_1_0_8RC2:1.8.2.12
	TIGRIS_1_0_8RC1:1.8.2.12
	TIGRIS_1_0_7:1.8.2.12
	TIGRIS_1_0_7RC3:1.8.2.12
	TIGRIS_1_0_7RC2:1.8.2.12
	TIGRIS_1_0_7RC1:1.8.2.12
	TIGRIS_1_0_6:1.8.2.12
	TIGRIS_1_0_6RC5:1.8.2.12
	TIGRIS_1_0_6RC4:1.8.2.11
	TIGRIS_1_0_6RC3:1.8.2.9
	TIGRIS_1_0_6RC2:1.8.2.4
	TIGRIS_1_0_6RC1:1.8.2.4
	TIGRIS_1_0:1.8.0.2;
locks; strict;
comment	@# @;


1.19
date	2001.07.30.19.29.58;	author leonardr;	state dead;
branches;
next	1.18;

1.18
date	2001.06.13.23.07.35;	author leonardr;	state Exp;
branches;
next	1.17;

1.17
date	2001.06.12.23.14.50;	author leonardr;	state Exp;
branches;
next	1.16;

1.16
date	2001.06.12.00.35.14;	author leonardr;	state Exp;
branches;
next	1.15;

1.15
date	2001.06.11.21.50.41;	author leonardr;	state Exp;
branches;
next	1.14;

1.14
date	2001.06.07.03.05.58;	author leonardr;	state Exp;
branches;
next	1.13;

1.13
date	2001.06.07.01.58.21;	author leonardr;	state Exp;
branches;
next	1.12;

1.12
date	2001.06.06.22.32.42;	author dlr;	state Exp;
branches;
next	1.11;

1.11
date	2001.06.06.20.42.18;	author dlr;	state Exp;
branches;
next	1.10;

1.10
date	2001.06.05.18.54.43;	author leonardr;	state Exp;
branches;
next	1.9;

1.9
date	2001.06.05.18.53.08;	author leonardr;	state Exp;
branches;
next	1.8;

1.8
date	2001.06.01.17.06.32;	author leonardr;	state Exp;
branches
	1.8.2.1;
next	1.7;

1.7
date	2001.06.01.15.56.36;	author leonardr;	state Exp;
branches;
next	1.6;

1.6
date	2001.06.01.15.55.32;	author leonardr;	state Exp;
branches;
next	1.5;

1.5
date	2001.05.31.21.31.39;	author dlr;	state Exp;
branches;
next	1.4;

1.4
date	2001.05.31.21.30.09;	author leonardr;	state Exp;
branches;
next	1.3;

1.3
date	2001.05.31.21.08.37;	author leonardr;	state Exp;
branches;
next	1.2;

1.2
date	2001.05.31.14.57.34;	author leonardr;	state Exp;
branches;
next	1.1;

1.1
date	2001.05.31.06.13.11;	author dlr;	state Exp;
branches;
next	;

1.8.2.1
date	2001.06.01.19.18.08;	author leonardr;	state Exp;
branches;
next	1.8.2.2;

1.8.2.2
date	2001.06.04.17.26.56;	author leonardr;	state Exp;
branches;
next	1.8.2.3;

1.8.2.3
date	2001.06.05.21.13.42;	author leonardr;	state Exp;
branches;
next	1.8.2.4;

1.8.2.4
date	2001.06.06.20.41.02;	author dlr;	state Exp;
branches;
next	1.8.2.5;

1.8.2.5
date	2001.06.07.21.24.15;	author leonardr;	state Exp;
branches;
next	1.8.2.6;

1.8.2.6
date	2001.06.07.22.01.09;	author stack;	state Exp;
branches;
next	1.8.2.7;

1.8.2.7
date	2001.06.07.22.06.39;	author leonardr;	state Exp;
branches;
next	1.8.2.8;

1.8.2.8
date	2001.06.07.22.39.20;	author leonardr;	state Exp;
branches;
next	1.8.2.9;

1.8.2.9
date	2001.06.11.22.03.30;	author leonardr;	state Exp;
branches;
next	1.8.2.10;

1.8.2.10
date	2001.06.12.01.15.30;	author leonardr;	state Exp;
branches;
next	1.8.2.11;

1.8.2.11
date	2001.06.13.00.00.18;	author leonardr;	state Exp;
branches;
next	1.8.2.12;

1.8.2.12
date	2001.06.13.23.14.19;	author leonardr;	state Exp;
branches;
next	;


desc
@@


1.19
log
@Stop coddling IZ in terms of user accounts; assume that IZ can get its permissions from Helm through the XML-RPC interface.
@
text
@/* ================================================================
 * Copyright (c) 2001 CollabNet.  All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 * 
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * 
 * 3. The end-user documentation included with the redistribution, if
 * any, must include the following acknowlegement: "This product includes
 * software developed by CollabNet (http://www.collab.net/)."
 * Alternately, this acknowlegement may appear in the software itself, if
 * and wherever such third-party acknowlegements normally appear.
 * 
 * 4. The hosted project names must not be used to endorse or promote
 * products derived from this software without prior written
 * permission. For written permission, please contact info@@collab.net.
 * 
 * 5. Products derived from this software may not use the "Tigris" name
 * nor may "Tigris" appear in their names without prior written
 * permission of CollabNet.
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL COLLABNET OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ====================================================================
 * 
 * This software consists of voluntary contributions made by many
 * individuals on behalf of CollabNet.
 */


package org.tigris.helm.tool.task;

import java.util.*;
import javax.servlet.ServletConfig;

import org.apache.velocity.context.Context;

import org.apache.turbine.services.*;
import org.apache.turbine.util.TurbineException;
import org.apache.turbine.util.db.pool.DBConnection;
import org.apache.turbine.util.Log;
import org.apache.turbine.services.velocity.TurbineVelocity;

import org.tigris.helm.tool.cluster.ClusteredSingletonService;
import org.tigris.helm.om.*;
import org.tigris.helm.DoesNotExist;
import org.tigris.helm.tool.HelmEmailer;
import org.tigris.helm.tool.TemplateTool;

/**
 * A cluster-wide singleton which constantly processes requests to rebuild
 * projects' issue tracking accounts.
 *
 * @@author <a href="mailto:leonardr@@collab.net">Leonard Richardson</a>
 * @@author <a href="mailto:dlr@@collab.net">Daniel Rall</a>
 */
public class IssueTrackingRebuildService extends ClusteredSingletonService
{
    /**
     * Whether or not to log debugging information
     */
    private static final boolean DEBUG = false;

    /**
     * The name of this service.  Used to retrive it from the broker.
     */
    public static final String SERVICE_NAME = "IssueTrackingRebuildService";

    /**
     * The number of times a rebuild can fail before admins get
     * notified.  
     */
    public static final int MAX_CONSECUTIVE_FAILURES = 10;

    /**
     * The name of the template used to create the body of the email
     * sent to admins when a project's issue tracking consistently
     * fails. 
     */
    private static final String REBUILD_FAILURE_TEMPLATE = 
        TemplateTool.getPathToMessageTemplate("IssueTrackingRebuildFailed.vm");

    /**
     * Subject of the email sent to admins when a project's issue
     * tracking consistently fails. The name of the project that
     * failed will be appended to the end.
     */
    private static final String REBUILD_FAILURE_SUBJECT = 
        "Issue tracking rebuild failure: ";

    /**
     * The average time a rebuild has taken so far; used to guess
     * whether or not the service can run another rebuild before it
     * needs to poll again. 
     */
    private static long averageRebuildTime = 0;

    /**
     * The number of rebuilds that have taken place.
     */
    private static int rebuildCount = 0;

    /**
     * The number of mail-generating failures which have occured.
     */
    private static int failureCount = 0;

    /**
     * The number of consecutive rebuild failures for projects.
     */
    private static Map rebuildFailureCounts = new HashMap();

    /**
     * Keeps track of which rebuild failures have had emails sent
     * about them.  Used to prevent admins from being swamped with
     * emails about a broken project.  
     */
    private static Set persistentRebuildFailures = new HashSet();

    /**
     * Returns the status of this service. 
     */
    public final String getStatus()
        throws TurbineException
    {
        int unrebuiltProjects = 0;
        try
        {
            unrebuiltProjects = getUnrebuiltProjectInformation().size();
        }
        catch (Exception e)
        {
            throw new TurbineException(e);
        }
        int persistentFailures = persistentRebuildFailures.size();
        StringBuffer b = new StringBuffer("").append(unrebuiltProjects)
            .append(" outstanding rebuild request")
            .append(rebuildCount==1 ? "" : "s").append(".\n");

        b.append(rebuildCount)
            .append(" successful rebuild")
            .append(rebuildCount==1 ? "" : "s").append(", ")
            .append(failureCount).append(" rebuild failure")
            .append(failureCount==1 ? "" : "s").append(".\n");

        b.append(persistentFailures).append(" project")
            .append(persistentFailures==1 ? "" : "s")
            .append(" currently failing rebuilds).\n");

        b.append("Average rebuild time: ").append(averageRebuildTime)
            .append("ms.");
        return b.toString();
    }

    /**
     * Descriptor for this singleton's timestamp event.
     */
    public final String getDescriptor()
    {
        return SERVICE_NAME;
    }

    /**
     * Returns the time it takes to rebuild an average project on
     * this system.
     */
    public long getAverageRebuildTime()
    {
        return averageRebuildTime;
    }

    /**
     * Returns the time, in milliseconds, which must elapse before a
     * claim on a singleton is considered dead.
     */
    public long getTimeout()
    {
        return 1000 * 60 * 3;
    }

    /**
     * A wrapper method for getting the single instance of this
     * service from the Turbine services list.
     *
     * @@return Turbine's single instance of this service.
     */
    public static final IssueTrackingRebuildService getService()
    {
        return (IssueTrackingRebuildService)TurbineServices.getInstance()
            .getService(SERVICE_NAME);
    }

    /**
     * Constructor; initialize to not being the singleton.
     */
    public IssueTrackingRebuildService()
    {
        isSingleton = false;
    }

    /**
     * This method is called every time the singleton reasserts itself
     * as the singleton.
     */
    public void doService()
        throws Exception
    {
        if (DEBUG)
        {
            Log.debug(rebuildCount + " rebuild(s) have taken place.");
            Log.debug("Average rebuild time: " + averageRebuildTime + "ms");
        }

        long started = System.currentTimeMillis();
        //Get the requests which have yet to be fulfilled;
        List toRebuild = getUnrebuiltProjectInformation();
        if (DEBUG)
        {
            Log.debug(toRebuild.size() + " projects have to be rebuilt.");
        }

        for (Iterator i = toRebuild.iterator(); i.hasNext();)
        {
            //Get the oldest unfulfilled rebuild request.
            ClusterEvent e = (ClusterEvent)i.next();

            //Rebuild the project.
            long before = System.currentTimeMillis();            
            String projectID = e.getDescriptor().toString();
            try
            {
                Project p = ProjectPeer.getInstance(projectID);
                if (DEBUG)
                {
                    Log.debug("Rebuilding issue tracking for " + p.getName());
                }
                boolean ran = false;
                try 
                {
                    p.doIssueTrackingRebuild();
                    
                    //Since we've done a successful rebuild, this project
                    //no longer has a persistent rebuild failure (if it
                    //did before).
                    persistentRebuildFailures.remove(p);
                    
                    ClusterEventPeer.deleteInstance(getName(), projectID);
                    if (DEBUG)
                    {
                        Log.debug("Done rebuilding issue tracking for " +
                                  p.getName());
                    }

                    long after = System.currentTimeMillis();
                    long duration = after-before;
                    averageRebuildTime = 
                        ((rebuildCount * averageRebuildTime) + duration)
                        / (rebuildCount + 1);
                    rebuildCount++;                
                    rebuildFailureCounts.remove(p);
                }
                catch (Exception ex)
                {
                    handleFailure(p);
                    e.setStamp(new Date());
                    e.save();
                }
            }
            catch (DoesNotExist ex)
            {
                //This project was deleted after we got the information
                //about its request; we can just ignore the request now.
                ClusterEventPeer.deleteInstance(getName(), projectID);
            }

            //See whether or not we have time to rebuild another project.
            if ((started + getPollTime()) >= (System.currentTimeMillis()
                                              + averageRebuildTime))
            {
                //We probably won't have time; wait until next poll.
                break;
            }
        }
    }

    /**
     * Returns information about the projects which have have
     * unfulfilled build requests.
     */
    public List getUnrebuiltProjectInformation()
        throws Exception
    {
        return ClusterEventPeer.getInstances(getName());
    }

    /**
     * Registers a project and its permissionable subprojects to be
     * rebuilt.
     */
    public void registerProject(Project project)
        throws Exception
    {
        List permissionedChildren = project.getPermissionedChildren();
        List toRemove = new ArrayList();
        for (Iterator i = permissionedChildren.iterator(); i.hasNext();)
        {
            Project p = (Project)i.next();
            if (p.isHost() || p.isDomain())
            {
                toRemove.add(p);
            }
        }
        permissionedChildren.removeAll(toRemove);

        String[] ids = new String[permissionedChildren.size()];
        int ct = 0;

        for (Iterator i = permissionedChildren.iterator(); i.hasNext();)
        {
            Project p = (Project)i.next();
            ids[ct++] = p.getID();
        }
        ClusterEventPeer.addEvents(getName(), ids);
    }   

    /**
     * Handles a failure of issue tracking rebuild for a project.  
     */
    public void handleFailure(Project project)
        throws Exception
    {
        Integer failuresSoFar = (Integer)rebuildFailureCounts.get(project);
        if (failuresSoFar == null)           
        {
            failuresSoFar = new Integer(1);
        }
        else
        {
            failuresSoFar = new Integer(failuresSoFar.intValue()+1);
        }

        if (failuresSoFar.intValue() < MAX_CONSECUTIVE_FAILURES)
        {
            rebuildFailureCounts.put(project, failuresSoFar);
        }
        else
        {
            //Send mail, if we haven't already sent mail about this
            //problem, and if there isn't a ProjectAdd for this project
            //in the task list which might clear up this problem.
            if (!persistentRebuildFailures.contains(project)
                && !TaskPeer.pendingTaskExists
                (HelmTask.COMPONENT_NAME, HelmTask.PROJECT_ADD_COMMAND, 
                 project.getID()))
            {            
                String subject = REBUILD_FAILURE_SUBJECT + 
                    project.getDomain().getName() + '/' + project.getName();
                Context ctx = TurbineVelocity.getContext();
                ctx.put("attempts", failuresSoFar);
                ctx.put("project", project);
                String body = TurbineVelocity.handleRequest
                    (ctx, REBUILD_FAILURE_TEMPLATE);
                HelmEmailer emailer = new HelmEmailer();
                emailer.sendError(subject, body.toString());
                
                persistentRebuildFailures.add(project);
            }

            //Reset the failure counter.
            rebuildFailureCounts.remove(project);
            failureCount++;
        }
    }

    /**
     * Returns the set of projects which known persistent issue
     * tracking rebuild failures which have yet to be remedied.  
     */
    public Set getFailures()
    {        
        return persistentRebuildFailures;
    }
}
@


1.18
log
@Don't send warning email if there's a ProjectAdd task in the task list which might resolve the problem.
@
text
@@


1.17
log
@Handle problems that occur when a project gets deleted and you were planning on processing a request for it.
@
text
@d366 6
a371 2
            //problem.
            if (!persistentRebuildFailures.contains(project))
@


1.16
log
@Persistent failures are now visible from the outside, since it's useful information.
@
text
@d63 1
d247 1
a247 2
            Project p = ProjectPeer.getInstance(projectID);
            if (DEBUG)
d249 1
a249 13
                Log.debug("Rebuilding issue tracking for " + p.getName());
            }
            boolean ran = false;
            try 
            {
                p.doIssueTrackingRebuild();

                //Since we've done a successful rebuild, this project
                //no longer has a persistent rebuild failure (if it
                //did before).
                persistentRebuildFailures.remove(p);

                ClusterEventPeer.deleteInstance(getName(), projectID);
d252 32
a283 2
                    Log.debug("Done rebuilding issue tracking for " +
                              p.getName());
a284 8

                long after = System.currentTimeMillis();
                long duration = after-before;
                averageRebuildTime = 
                    ((rebuildCount * averageRebuildTime) + duration)
                    / (rebuildCount + 1);
                rebuildCount++;                
                rebuildFailureCounts.remove(p);
d286 1
a286 1
            catch (Exception ex)
d288 3
a290 3
                handleFailure(p);
                e.setStamp(new Date());
                e.save();
@


1.15
log
@Keep track of sent failure email so the same failure doesn't trigger multiple emails.
@
text
@d127 1
a127 1
    private static Map rebuildFailures = new HashMap();
d134 1
a134 1
    private static Set sentEmails = new HashSet();
d151 1
d159 6
a164 3
            .append(failureCount).append(" persistent rebuild failure")
            .append(failureCount==1 ? "" : "s")
            .append(".\n");
d256 4
a259 3
                //Since we've done a successful rebuild, any subsequent
                //failure should generate email.
                sentEmails.remove(p);
d274 1
a274 1
                rebuildFailures.remove(p);
d339 1
a339 1
        Integer failuresSoFar = (Integer)rebuildFailures.get(project);
d351 1
a351 1
            rebuildFailures.put(project, failuresSoFar);
d357 1
a357 1
            if (!sentEmails.contains(project))
d368 2
a369 2

                sentEmails.add(project);
d373 1
a373 1
            rebuildFailures.remove(project);
d376 9
@


1.14
log
@Method to return average rebuild time.
@
text
@d130 7
d251 5
d344 1
a344 1
        if (failuresSoFar.intValue() <= MAX_CONSECUTIVE_FAILURES)
d350 16
a365 10
            //Send mail.
            String subject = REBUILD_FAILURE_SUBJECT + 
                project.getDomain().getName() + '/' + project.getName();
            Context ctx = TurbineVelocity.getContext();
            ctx.put("attempts", failuresSoFar);
            ctx.put("project", project);
            String body = TurbineVelocity.handleRequest
                (ctx, REBUILD_FAILURE_TEMPLATE);
            HelmEmailer emailer = new HelmEmailer();
            emailer.sendError(subject, body.toString());
@


1.13
log
@Added placeholder HelmService interface.
@
text
@d169 9
@


1.12
log
@Gated more debugging trace behind conditional compilation.
@
text
@d56 1
d128 31
@


1.11
log
@Only print this information when compiled in DEBUG mode.
@
text
@d181 5
a185 1
        Log.debug(toRebuild.size() + " projects have to be rebuilt.");
d195 4
a198 1
            Log.debug("Rebuilding issue tracking for " + p.getName());
d204 5
a208 1
                Log.debug("Done rebuilding issue tracking for " + p.getName());
a219 1
                Log.debug("Bitter failure!");
@


1.10
log
@Velocity in the HEAD, Webmacro in the branch.
@
text
@d172 6
a177 2
        Log.debug(rebuildCount + " rebuild(s) have taken place.");
        Log.debug("Average rebuild time: " + averageRebuildTime + "ms");
@


1.9
log
@Added more functionality for role deletion.
@
text
@d96 1
a96 1
        TemplateTool.getPathToMessageTemplate("IssueTrackingRebuildFailed.wm");
@


1.8
log
@Added section to TaskList to display currently unfulfilled issue tracking rebuild requests.
@
text
@d96 1
a96 1
        TemplateTool.getPathToMessageTemplate("IssueTrackingRebuildFailed.vm");
@


1.8.2.1
log
@Ported minimal cluster functionality so that I could also port IssueTrackingRebuildService, which builds on it.
@
text
@d238 1
a238 1
        List permissionedChildren = project.selfAndChildren();
@


1.8.2.2
log
@Removed references to Velocity.
@
text
@d53 1
a53 1
import org.webmacro.servlet.WebContext;
d58 1
a58 1
import org.apache.turbine.services.webmacro.TurbineWebMacro;
d286 1
a286 1
            WebContext ctx = TurbineWebMacro.getContext();
d289 1
a289 1
            String body = TurbineWebMacro.handleRequest
@


1.8.2.3
log
@Put in workaround for annoying but thankfully archaic Turbine bug.
@
text
@d208 1
a208 1
                e.replace();
@


1.8.2.4
log
@Only print this information when compiled in DEBUG mode.
@
text
@d172 2
a173 6
        if (DEBUG)
        {
            Log.debug(rebuildCount + " rebuild(s) have taken place.");
            Log.debug("Average rebuild time: " + averageRebuildTime + "ms");
        }

@


1.8.2.5
log
@Sidestep Turbine altogether for this thing that causes the quoting bug.
@
text
@d211 2
a212 1
                e.saveNewStamp();
@


1.8.2.6
log
@1.0.x does not use velocity templates.  Change '.vm' suffix to '.wm'
so we pick up the webmacro version of ITRFailed template.
@
text
@d96 1
a96 1
        TemplateTool.getPathToMessageTemplate("IssueTrackingRebuildFailed.wm");
@


1.8.2.7
log
@Fixed bonehead SQL error and added better logging.
@
text
@d209 1
a209 1
                Log.debug("Bitter failure: " + ex);
@


1.8.2.8
log
@Gated debug statements.
@
text
@d181 1
a181 4
        if (DEBUG)
        {
            Log.debug(toRebuild.size() + " projects have to be rebuilt.");
        }
d191 1
a191 4
            if (DEBUG)
            {
                Log.debug("Rebuilding issue tracking for " + p.getName());
            }
d197 1
a197 5
                if (DEBUG)
                {
                    Log.debug("Done rebuilding issue tracking for " 
                              + p.getName());
                }
d209 1
a209 4
                if (DEBUG)
                {
                    Log.debug("Rebuild failed: " + ex);
                }
@


1.8.2.9
log
@Ported issue tracking rebuild enhancements over to branch.
@
text
@a128 7
     * Keeps track of which rebuild failures have had emails sent
     * about them.  Used to prevent admins from being swamped with
     * emails about a broken project.  
     */
    private static Set sentEmails = new HashSet();

    /**
a201 5

                //Since we've done a successful rebuild, any subsequent
                //failure should generate email.
                sentEmails.remove(p);

d299 10
a308 16
            //Send mail, if we haven't already sent mail about this
            //problem.
            if (!sentEmails.contains(project))
            {            
                String subject = REBUILD_FAILURE_SUBJECT + 
                    project.getDomain().getName() + '/' + project.getName();
                WebContext ctx = TurbineWebMacro.getContext();
                ctx.put("attempts", failuresSoFar);
                ctx.put("project", project);
                String body = TurbineWebMacro.handleRequest
                    (ctx, REBUILD_FAILURE_TEMPLATE);
                HelmEmailer emailer = new HelmEmailer();
                emailer.sendError(subject, body.toString());

                sentEmails.add(project);
            }
@


1.8.2.10
log
@Ported over observation of persistent issue tracking rebuild failures.
@
text
@d126 1
a126 1
    private static Map rebuildFailureCounts = new HashMap();
d133 1
a133 1
    private static Set rebuildFailures = new HashSet();
d212 1
a212 1
                rebuildFailures.remove(p);
d227 1
a227 1
                rebuildFailureCounts.remove(p);
d295 1
a295 1
        Integer failuresSoFar = (Integer)rebuildFailureCounts.get(project);
d307 1
a307 1
            rebuildFailureCounts.put(project, failuresSoFar);
d313 1
a313 1
            if (!rebuildFailures.contains(project))
d325 1
a325 1
                rebuildFailures.add(project);
d329 1
a329 1
            rebuildFailureCounts.remove(project);
a332 10
    
    /**
     * Returns the set of projects which known persistent issue
     * tracking rebuild failures which have yet to be remedied.  
     */
    public Set getFailures()
    {
        return rebuildFailures;
    }

@


1.8.2.11
log
@Handle errors when a project gets deleted out from under you.
@
text
@a61 1
import org.tigris.helm.DoesNotExist;
d200 2
a201 1
            try
d203 12
a214 1
                Project p = ProjectPeer.getInstance(projectID);
d217 2
a218 1
                    Log.debug("Rebuilding issue tracking for " + p.getName());
d220 12
a231 25
                boolean ran = false;
                try 
                {
                    p.doIssueTrackingRebuild();
                    
                    //Since we've done a successful rebuild, any subsequent
                    //failure should generate email.
                    rebuildFailures.remove(p);
                    
                    ClusterEventPeer.deleteInstance(getName(), projectID);
                    if (DEBUG)
                    {
                        Log.debug("Done rebuilding issue tracking for " 
                                  + p.getName());
                    }
                    
                    long after = System.currentTimeMillis();
                    long duration = after-before;
                    averageRebuildTime = 
                        ((rebuildCount * averageRebuildTime) + duration)
                        / (rebuildCount + 1);
                    rebuildCount++;                
                    rebuildFailureCounts.remove(p);
                }
                catch (Exception ex)
d233 1
a233 6
                    if (DEBUG)
                    {
                        Log.debug("Rebuild failed: " + ex);
                    }
                    handleFailure(p);
                    e.saveNewStamp();
d235 2
a236 6
            }
            catch (DoesNotExist ex)
            {
                //This project was deleted after we got the information
                //about its request; we can just ignore the request now.
                ClusterEventPeer.deleteInstance(getName(), projectID);
@


1.8.2.12
log
@Ported over ITR failure mail reduction code from HEAD.
@
text
@d321 3
a323 6
            //problem, and if there isn't a ProjectAdd for this project
            //in the task list which might clear up this problem.
            if (!rebuildFailures.contains(project)
                && !TaskPeer.pendingTaskExists
                (HelmTask.COMPONENT_NAME, HelmTask.PROJECT_ADD_COMMAND,
                 project.getID()))    
@


1.7
log
@Removed accidentally committed test code.
@
text
@d176 1
a176 1
        List toRebuild = ClusterEventPeer.getNonSingletonInstances(getName());
d219 10
@


1.6
log
@Implemented singleton service stopping.
@
text
@a171 5
        /*        for (Iterator i = ((TurbineServices)TurbineServices.getInstance())
                 .getServiceNames(); i.hasNext();)
        {
        }*/

@


1.5
log
@* Removed non-applicable header JavaDoc.

* Adjective/noun combinations make better variable names that straight
nouns.  Tweaked members and their use accordingly.
@
text
@d172 5
@


1.4
log
@Properly refrain from registering host or domain projects.
@
text
@a68 3
 * Use of <code>Thread.stop()</code> is avoided as <a href="http://java.sun.com/products/jdk//1.2/docs/guide/misc/threadPrimitiveDeprecation.html">described
 * by JavaSoft</a>.
 *
d70 1
a70 1
 * @@version $Id: IssueTrackingRebuildService.java,v 1.3 2001/05/31 21:08:37 leonardr Exp $
d116 1
a116 1
    private static int rebuilds = 0;
d121 1
a121 1
    private static int failures = 0;
d172 1
a172 1
        Log.debug(rebuilds + " rebuild(s) have taken place.");
d198 3
a200 3
                    ((rebuilds*averageRebuildTime) + duration)
                    / (rebuilds+1);                
                rebuilds++;                
d286 1
a286 1
            failures++;
@


1.3
log
@Added error reporting capabilities to issue tracking rebuild.
@
text
@d73 1
a73 1
 * @@version $Id: IssueTrackingRebuildService.java,v 1.2 2001/05/31 14:57:34 leonardr Exp $
d232 11
d245 1
d249 1
a249 4
            if (!(p.isHost() || p.isDomain()))
            {
                ids[ct++] = p.getID();
            }
@


1.2
log
@Keep statistics and use them to determine whether or not another rebuild can be completed before the next poll time.
@
text
@d53 2
d58 1
d62 2
d73 1
a73 1
 * @@version $Id: IssueTrackingRebuildService.java,v 1.1 2001/05/31 06:13:11 dlr Exp $
d88 22
d122 10
d195 3
d204 1
a204 1
                ran = true;
d208 2
a209 2
                //Something went wrong; reset the timestamp;
                Log.debug("Something went wrong, resetting timestamp.");
a213 10
            if (ran)
            {
                Log.debug("Done rebuilding issue tracking for " + p.getName());
                
                //Remove the rebuild event from the database.
                Log.debug("Deleting instance.");
                ClusterEventPeer.deleteInstance(getName(), projectID);
                Log.debug("Done.");
            }            

d218 1
a218 2
                //We probably won't have time; poll again.
                Log.debug("Out of time!");
d237 4
a240 1
            ids[ct++] = p.getID();
d244 39
@


1.1
log
@Leonard's Turbine service for handling issue tracking rebuilds.
@
text
@d68 1
a68 1
 * @@version $Id: TaskRunnerService.java,v 1.26 2001/05/22 20:34:56 leonardr Exp $
d83 12
d138 3
a140 1
        Date started = new Date();
d150 1
d158 6
d185 2
a186 2
            if (started.before
                (new Date(System.currentTimeMillis()-getPollTime())))
d188 1
a188 2
                //We need to poll again; we might not be the singleton
                //anymore.
a190 4
            }
            else
            {
                Log.debug("Let's try another.");
@

