taskjuggler 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +44 -0
- data/bin/tj3webd +4 -0
- data/data/css/tjreport.css +14 -5
- data/data/tjp.vim +22 -7
- data/examples/Fedora-20/reports.tji +2 -4
- data/examples/Scrum/Product Burndown.csv +26 -0
- data/examples/Scrum/Sprint 1 Burndown.csv +26 -0
- data/examples/Scrum/Sprint 2 Burndown.csv +26 -0
- data/examples/Scrum/Sprint 3 Burndown.csv +26 -0
- data/examples/Scrum/scrum.tjp +141 -0
- data/examples/Tutorial/tutorial.tjp +13 -7
- data/lib/taskjuggler/Attributes.rb +2 -3
- data/lib/taskjuggler/HTMLDocument.rb +25 -18
- data/lib/taskjuggler/Journal.rb +85 -65
- data/lib/taskjuggler/KeywordDocumentation.rb +25 -13
- data/lib/taskjuggler/LeaveList.rb +1 -1
- data/lib/taskjuggler/Limits.rb +3 -5
- data/lib/taskjuggler/MessageHandler.rb +173 -19
- data/lib/taskjuggler/Painter.rb +75 -0
- data/lib/taskjuggler/Painter/BasicShapes.rb +76 -0
- data/lib/taskjuggler/Painter/Color.rb +273 -0
- data/lib/taskjuggler/Painter/Element.rb +56 -0
- data/lib/taskjuggler/Painter/FontData.rb +221 -0
- data/lib/taskjuggler/Painter/FontMetrics.rb +125 -0
- data/lib/taskjuggler/Painter/FontMetricsData.rb +151 -0
- data/lib/taskjuggler/Painter/Group.rb +77 -0
- data/lib/taskjuggler/Painter/Points.rb +47 -0
- data/lib/taskjuggler/Painter/Primitives.rb +100 -0
- data/lib/taskjuggler/Painter/SVGSupport.rb +36 -0
- data/lib/taskjuggler/Painter/Text.rb +36 -0
- data/lib/taskjuggler/Project.rb +46 -29
- data/lib/taskjuggler/ProjectFileParser.rb +24 -22
- data/lib/taskjuggler/ProjectFileScanner.rb +2 -2
- data/lib/taskjuggler/PropertyTreeNode.rb +26 -34
- data/lib/taskjuggler/Query.rb +8 -5
- data/lib/taskjuggler/RealFormat.rb +3 -0
- data/lib/taskjuggler/Resource.rb +3 -5
- data/lib/taskjuggler/ResourceScenario.rb +19 -7
- data/lib/taskjuggler/RichText.rb +4 -6
- data/lib/taskjuggler/RichText/FunctionExample.rb +1 -1
- data/lib/taskjuggler/RichText/FunctionHandler.rb +5 -6
- data/lib/taskjuggler/RichText/Parser.rb +4 -6
- data/lib/taskjuggler/RichText/RTFNavigator.rb +1 -1
- data/lib/taskjuggler/RichText/RTFQuery.rb +2 -3
- data/lib/taskjuggler/RichText/RTFReport.rb +1 -1
- data/lib/taskjuggler/RichText/RTFReportLink.rb +1 -2
- data/lib/taskjuggler/RichText/RTFWithQuerySupport.rb +1 -1
- data/lib/taskjuggler/RichText/Scanner.rb +6 -6
- data/lib/taskjuggler/RichText/Snip.rb +1 -2
- data/lib/taskjuggler/RuntimeConfig.rb +9 -6
- data/lib/taskjuggler/ScenarioData.rb +4 -3
- data/lib/taskjuggler/Scoreboard.rb +6 -0
- data/lib/taskjuggler/SheetHandlerBase.rb +25 -8
- data/lib/taskjuggler/SimpleQueryExpander.rb +14 -5
- data/lib/taskjuggler/SyntaxReference.rb +1 -2
- data/lib/taskjuggler/TableColumnSorter.rb +84 -0
- data/lib/taskjuggler/Task.rb +3 -5
- data/lib/taskjuggler/TaskJuggler.rb +36 -29
- data/lib/taskjuggler/TaskScenario.rb +154 -66
- data/lib/taskjuggler/TextParser.rb +24 -17
- data/lib/taskjuggler/TextParser/Scanner.rb +16 -11
- data/lib/taskjuggler/TextParser/SourceFileInfo.rb +20 -15
- data/lib/taskjuggler/TimeSheets.rb +6 -12
- data/lib/taskjuggler/Tj3AppBase.rb +35 -16
- data/lib/taskjuggler/Tj3Config.rb +1 -1
- data/lib/taskjuggler/TjpSyntaxRules.rb +239 -49
- data/lib/taskjuggler/XMLElement.rb +9 -2
- data/lib/taskjuggler/apps/Tj3.rb +43 -37
- data/lib/taskjuggler/apps/Tj3Client.rb +62 -112
- data/lib/taskjuggler/apps/Tj3Daemon.rb +66 -29
- data/lib/taskjuggler/apps/Tj3Man.rb +5 -5
- data/lib/taskjuggler/apps/Tj3SsReceiver.rb +10 -13
- data/lib/taskjuggler/apps/Tj3SsSender.rb +13 -16
- data/lib/taskjuggler/apps/Tj3TsReceiver.rb +10 -13
- data/lib/taskjuggler/apps/Tj3TsSender.rb +12 -15
- data/lib/taskjuggler/apps/Tj3TsSummary.rb +12 -15
- data/lib/taskjuggler/apps/Tj3WebD.rb +99 -0
- data/lib/taskjuggler/daemon/Daemon.rb +50 -10
- data/lib/taskjuggler/daemon/DaemonConnector.rb +127 -0
- data/lib/taskjuggler/daemon/ProcessIntercom.rb +36 -21
- data/lib/taskjuggler/daemon/ProjectBroker.rb +122 -112
- data/lib/taskjuggler/daemon/ProjectServer.rb +78 -46
- data/lib/taskjuggler/daemon/ReportServer.rb +52 -28
- data/lib/taskjuggler/daemon/ReportServlet.rb +92 -21
- data/lib/taskjuggler/daemon/WebServer.rb +75 -22
- data/lib/taskjuggler/daemon/WelcomePage.rb +1 -0
- data/lib/taskjuggler/reports/AccountListRE.rb +3 -3
- data/lib/taskjuggler/reports/CSVFile.rb +9 -2
- data/lib/taskjuggler/reports/ChartPlotter.rb +453 -0
- data/lib/taskjuggler/reports/Navigator.rb +1 -0
- data/lib/taskjuggler/reports/NikuReport.rb +4 -4
- data/lib/taskjuggler/reports/Report.rb +6 -18
- data/lib/taskjuggler/reports/ReportBase.rb +9 -9
- data/lib/taskjuggler/reports/ReportContext.rb +2 -2
- data/lib/taskjuggler/reports/StatusSheetReport.rb +6 -6
- data/lib/taskjuggler/reports/TableReport.rb +24 -15
- data/lib/taskjuggler/reports/TimeSheetReport.rb +5 -5
- data/lib/taskjuggler/reports/TraceReport.rb +251 -0
- data/lib/tj3webd.rb +17 -0
- data/manual/Day_To_Day_Juggling +10 -3
- data/manual/Installation +38 -19
- data/manual/Software +25 -19
- data/manual/Tutorial +119 -110
- data/manual/html/Day_To_Day_Juggling.html +7 -5
- data/manual/html/Getting_Started.html +4 -4
- data/manual/html/How_To_Contribute.html +4 -4
- data/manual/html/Installation.html +19 -11
- data/manual/html/Intro.html +4 -4
- data/manual/html/Reporting_Bugs.html +4 -4
- data/manual/html/Rich_Text_Attributes.html +4 -4
- data/manual/html/Software.html +15 -11
- data/manual/html/TaskJuggler_2x_Migration.html +4 -4
- data/manual/html/TaskJuggler_Internals.html +4 -4
- data/manual/html/The_TaskJuggler_Syntax.html +4 -4
- data/manual/html/Tutorial.html +41 -32
- data/manual/html/account.html +4 -4
- data/manual/html/account.task.html +4 -4
- data/manual/html/accountprefix.html +4 -4
- data/manual/html/accountreport.html +27 -9
- data/manual/html/accountroot.html +5 -5
- data/manual/html/active.html +4 -4
- data/manual/html/adopt.task.html +4 -4
- data/manual/html/aggregate.html +4 -4
- data/manual/html/alert.html +4 -4
- data/manual/html/alertlevels.html +4 -4
- data/manual/html/allocate.html +5 -5
- data/manual/html/alphabet.html +4 -4
- data/manual/html/alternative.html +4 -4
- data/manual/html/author.html +4 -4
- data/manual/html/balance.html +5 -5
- data/manual/html/booking.resource.html +4 -4
- data/manual/html/booking.task.html +4 -4
- data/manual/html/caption.html +5 -5
- data/manual/html/cellcolor.column.html +43 -8
- data/manual/html/celltext.column.html +4 -4
- data/manual/html/center.html +5 -5
- data/manual/html/charge.html +4 -4
- data/manual/html/chargeset.html +4 -4
- data/manual/html/columnid.html +27 -15
- data/manual/html/columns.html +5 -5
- data/manual/html/complete.html +4 -4
- data/manual/html/copyright.html +4 -4
- data/manual/html/credits.html +4 -4
- data/manual/html/css/tjreport.css +14 -5
- data/manual/html/currency.html +4 -4
- data/manual/html/currencyformat.html +5 -5
- data/manual/html/dailymax.html +5 -5
- data/manual/html/dailymin.html +5 -5
- data/manual/html/dailyworkinghours.html +4 -4
- data/manual/html/date.extend.html +4 -4
- data/manual/html/date.html +5 -5
- data/manual/html/definitions.html +4 -4
- data/manual/html/depends.html +4 -4
- data/manual/html/details.html +4 -4
- data/manual/html/disabled.html +4 -4
- data/manual/html/duration.html +4 -4
- data/manual/html/efficiency.html +4 -4
- data/manual/html/effort.html +4 -4
- data/manual/html/email.html +4 -4
- data/manual/html/enabled.html +4 -4
- data/manual/html/end.column.html +4 -4
- data/manual/html/end.html +4 -4
- data/manual/html/end.limit.html +4 -4
- data/manual/html/end.report.html +5 -5
- data/manual/html/end.timesheet.html +4 -4
- data/manual/html/endcredit.html +4 -4
- data/manual/html/epilog.html +5 -5
- data/manual/html/export.html +4 -4
- data/manual/html/extend.html +4 -4
- data/manual/html/fail.html +43 -8
- data/manual/html/fdl.html +4 -4
- data/manual/html/flags.account.html +4 -4
- data/manual/html/flags.html +4 -4
- data/manual/html/flags.journalentry.html +4 -4
- data/manual/html/flags.report.html +5 -5
- data/manual/html/flags.resource.html +4 -4
- data/manual/html/flags.statussheet.html +4 -4
- data/manual/html/flags.task.html +4 -4
- data/manual/html/flags.timesheet.html +4 -4
- data/manual/html/fontcolor.column.html +43 -8
- data/manual/html/footer.html +5 -5
- data/manual/html/formats.html +5 -5
- data/manual/html/functions.html +4 -4
- data/manual/html/gapduration.html +4 -4
- data/manual/html/gaplength.html +4 -4
- data/manual/html/halign.center.html +4 -4
- data/manual/html/halign.column.html +43 -8
- data/manual/html/halign.left.html +4 -4
- data/manual/html/halign.right.html +4 -4
- data/manual/html/hasalert.html +4 -4
- data/manual/html/header.html +5 -5
- data/manual/html/headline.html +7 -7
- data/manual/html/height.html +72 -0
- data/manual/html/hideaccount.html +46 -11
- data/manual/html/hidejournalentry.html +5 -5
- data/manual/html/hidereport.html +43 -8
- data/manual/html/hideresource.html +44 -9
- data/manual/html/hidetask.html +44 -9
- data/manual/html/icalreport.html +4 -4
- data/manual/html/include.macro.html +4 -4
- data/manual/html/include.project.html +4 -4
- data/manual/html/include.properties.html +4 -4
- data/manual/html/index.html +2 -1
- data/manual/html/inherit.extend.html +4 -4
- data/manual/html/interval1.html +4 -4
- data/manual/html/interval2.html +4 -4
- data/manual/html/interval3.html +4 -4
- data/manual/html/interval4.html +4 -4
- data/manual/html/isactive.html +4 -4
- data/manual/html/ischildof.html +4 -4
- data/manual/html/isdependencyof.html +4 -4
- data/manual/html/isdutyof.html +4 -4
- data/manual/html/isfeatureof.html +4 -4
- data/manual/html/isleaf.html +4 -4
- data/manual/html/ismilestone.html +4 -4
- data/manual/html/isongoing.html +4 -4
- data/manual/html/isresource.html +4 -4
- data/manual/html/isresponsibilityof.html +4 -4
- data/manual/html/istask.html +4 -4
- data/manual/html/journalattributes.html +11 -7
- data/manual/html/journalentry.html +4 -4
- data/manual/html/journalmode.html +5 -5
- data/manual/html/leaveallowance.html +5 -5
- data/manual/html/leaves.html +5 -6
- data/manual/html/left.html +5 -5
- data/manual/html/length.html +4 -4
- data/manual/html/limits.allocate.html +4 -4
- data/manual/html/limits.html +4 -4
- data/manual/html/limits.resource.html +4 -4
- data/manual/html/limits.task.html +4 -4
- data/manual/html/listitem.column.html +4 -4
- data/manual/html/listtype.column.html +4 -4
- data/manual/html/loadunit.html +5 -5
- data/manual/html/logicalexpression.html +8 -44
- data/manual/html/logicalflagexpression.html +4 -4
- data/manual/html/macro.html +4 -4
- data/manual/html/managers.html +4 -4
- data/manual/html/mandatory.html +4 -4
- data/manual/html/maxend.html +4 -4
- data/manual/html/maximum.html +5 -5
- data/manual/html/maxstart.html +4 -4
- data/manual/html/milestone.html +4 -4
- data/manual/html/minend.html +4 -4
- data/manual/html/minimum.html +5 -5
- data/manual/html/minstart.html +4 -4
- data/manual/html/monthlymax.html +5 -5
- data/manual/html/monthlymin.html +5 -5
- data/manual/html/navbar.html +10 -4
- data/manual/html/navigator.html +4 -4
- data/manual/html/newtask.html +4 -4
- data/manual/html/nikureport.html +4 -4
- data/manual/html/note.task.html +4 -4
- data/manual/html/now.html +4 -4
- data/manual/html/numberformat.html +5 -5
- data/manual/html/onend.html +4 -4
- data/manual/html/onstart.html +4 -4
- data/manual/html/opennodes.html +5 -5
- data/manual/html/overtime.booking.html +4 -4
- data/manual/html/period.column.html +4 -4
- data/manual/html/period.limit.html +4 -4
- data/manual/html/period.report.html +5 -5
- data/manual/html/period.task.html +4 -4
- data/manual/html/persistent.html +4 -4
- data/manual/html/precedes.html +4 -4
- data/manual/html/priority.html +4 -4
- data/manual/html/priority.timesheet.html +4 -4
- data/manual/html/project.html +4 -4
- data/manual/html/projectid.html +4 -4
- data/manual/html/projectid.task.html +4 -4
- data/manual/html/projectids.html +4 -4
- data/manual/html/projection.html +5 -7
- data/manual/html/prolog.html +5 -5
- data/manual/html/properties.html +11 -5
- data/manual/html/purge.html +5 -5
- data/manual/html/rate.html +4 -4
- data/manual/html/rate.resource.html +4 -4
- data/manual/html/reference.extend.html +4 -4
- data/manual/html/remaining.html +4 -4
- data/manual/html/replace.html +4 -4
- data/manual/html/reportprefix.html +4 -4
- data/manual/html/resource.html +4 -10
- data/manual/html/resourceattributes.html +4 -4
- data/manual/html/resourceprefix.html +4 -4
- data/manual/html/resourcereport.html +28 -10
- data/manual/html/resourceroot.html +5 -5
- data/manual/html/resources.limit.html +4 -4
- data/manual/html/responsible.html +4 -4
- data/manual/html/richtext.extend.html +4 -4
- data/manual/html/right.html +5 -5
- data/manual/html/rollupaccount.html +44 -9
- data/manual/html/rollupresource.html +44 -9
- data/manual/html/rolluptask.html +44 -9
- data/manual/html/scale.column.html +4 -4
- data/manual/html/scenario.html +4 -22
- data/manual/html/scenario.ical.html +4 -4
- data/manual/html/scenarios.export.html +4 -4
- data/manual/html/scenarios.html +5 -5
- data/manual/html/scenariospecific.extend.html +4 -4
- data/manual/html/scheduled.html +4 -4
- data/manual/html/scheduling.html +4 -4
- data/manual/html/select.html +4 -4
- data/manual/html/selfcontained.html +5 -5
- data/manual/html/shift.allocate.html +4 -4
- data/manual/html/shift.html +4 -4
- data/manual/html/shift.resource.html +5 -5
- data/manual/html/shift.task.html +4 -4
- data/manual/html/shift.timesheet.html +4 -4
- data/manual/html/shifts.allocate.html +4 -4
- data/manual/html/shifts.resource.html +4 -4
- data/manual/html/shifts.task.html +4 -4
- data/manual/html/shorttimeformat.html +4 -4
- data/manual/html/sloppy.booking.html +4 -4
- data/manual/html/sloppy.projection.html +5 -5
- data/manual/html/sortaccounts.html +5 -5
- data/manual/html/sortjournalentries.html +5 -5
- data/manual/html/sortresources.html +5 -5
- data/manual/html/sorttasks.html +5 -5
- data/manual/html/start.column.html +4 -4
- data/manual/html/start.html +4 -4
- data/manual/html/start.limit.html +4 -4
- data/manual/html/start.report.html +5 -5
- data/manual/html/startcredit.html +4 -4
- data/manual/html/status.statussheet.html +4 -4
- data/manual/html/status.timesheet.html +4 -4
- data/manual/html/statussheet.html +4 -4
- data/manual/html/statussheetreport.html +4 -4
- data/manual/html/strict.projection.html +5 -5
- data/manual/html/summary.html +4 -4
- data/manual/html/supplement.html +4 -4
- data/manual/html/supplement.resource.html +4 -10
- data/manual/html/supplement.task.html +4 -28
- data/manual/html/tagfile.html +4 -4
- data/manual/html/task.html +4 -28
- data/manual/html/task.statussheet.html +4 -4
- data/manual/html/task.timesheet.html +4 -4
- data/manual/html/taskattributes.html +4 -4
- data/manual/html/taskprefix.html +4 -4
- data/manual/html/taskreport.html +28 -10
- data/manual/html/taskroot.html +5 -5
- data/manual/html/text.extend.html +4 -4
- data/manual/html/textreport.html +27 -9
- data/manual/html/timeformat.html +5 -5
- data/manual/html/timeoff.nikureport.html +4 -4
- data/manual/html/timesheet.html +4 -4
- data/manual/html/timesheetreport.html +23 -5
- data/manual/html/timezone.export.html +4 -4
- data/manual/html/timezone.html +4 -4
- data/manual/html/timezone.report.html +5 -5
- data/manual/html/timezone.shift.html +4 -4
- data/manual/html/timingresolution.html +4 -4
- data/manual/html/title.column.html +4 -4
- data/manual/html/title.html +5 -5
- data/manual/html/toc.html +207 -179
- data/manual/html/tooltip.column.html +45 -10
- data/manual/html/tracereport.html +405 -0
- data/manual/html/trackingscenario.html +6 -6
- data/manual/html/treelevel.html +4 -4
- data/manual/html/vacation.html +4 -4
- data/manual/html/vacation.resource.html +4 -4
- data/manual/html/vacation.shift.html +4 -4
- data/manual/html/warn.html +43 -8
- data/manual/html/weeklymax.html +5 -5
- data/manual/html/weeklymin.html +5 -5
- data/manual/html/weekstartsmonday.html +4 -4
- data/manual/html/weekstartssunday.html +6 -6
- data/manual/html/width.column.html +6 -6
- data/manual/html/width.html +72 -0
- data/manual/html/work.html +4 -4
- data/manual/html/workinghours.project.html +4 -4
- data/manual/html/workinghours.resource.html +4 -4
- data/manual/html/workinghours.shift.html +4 -4
- data/manual/html/yearlyworkingdays.html +4 -4
- data/spec/Color_spec.rb +60 -0
- data/spec/ProjectBroker_spec.rb +3 -2
- data/spec/StatusSheets_spec.rb +5 -4
- data/spec/TableColumnSorter_spec.rb +78 -0
- data/spec/TimeSheets_spec.rb +6 -2
- data/spec/Tj3Daemon_spec.rb +2 -2
- data/spec/TraceReport_spec.rb +117 -0
- data/taskjuggler.gemspec +1 -1
- data/test/MessageChecker.rb +3 -1
- data/test/ReferenceGenerator.rb +1 -1
- data/test/TestSuite/CSV-Reports/Leave.tjp +1 -1
- data/test/TestSuite/CSV-Reports/refs/resourcereport_with_tasks.csv +3 -0
- data/test/TestSuite/CSV-Reports/refs/taskcounter.csv +9 -0
- data/test/TestSuite/CSV-Reports/refs/taskreport_with_resources.csv +19 -16
- data/test/TestSuite/CSV-Reports/refs/weekly.csv +1 -0
- data/test/TestSuite/Export-Reports/refs/LogicalExpression.tjp +14 -2
- data/test/TestSuite/Export-Reports/refs/tutorial.tjp +98 -86
- data/test/TestSuite/Scheduler/Correct/Leaves.tjp +25 -0
- data/test/TestSuite/Syntax/Correct/Leave.tjp +1 -1
- data/test/TestSuite/Syntax/Correct/LogicalExpression.tjp +9 -1
- data/test/TestSuite/Syntax/Correct/TraceReport.tjp +10 -0
- data/test/TestSuite/Syntax/Correct/tutorial.tjp +10 -4
- data/test/test_CSV-Reports.rb +3 -3
- data/test/test_Export-Reports.rb +91 -86
- data/test/test_Journal.rb +15 -12
- data/test/test_Limits.rb +3 -3
- data/test/test_Project.rb +1 -2
- data/test/test_ProjectFileScanner.rb +1 -1
- data/test/test_PropertySet.rb +1 -1
- data/test/test_Query.rb +5 -6
- data/test/test_ReportGenerator.rb +15 -7
- data/test/test_RichText.rb +4 -3
- data/test/test_Scheduler.rb +19 -7
- data/test/test_ShiftAssignments.rb +2 -2
- data/test/test_SimpleQueryExpander.rb +29 -2
- data/test/test_Syntax.rb +14 -5
- metadata +49 -10
- data/lib/taskjuggler/LogFile.rb +0 -73
|
@@ -11,24 +11,36 @@
|
|
|
11
11
|
# published by the Free Software Foundation.
|
|
12
12
|
#
|
|
13
13
|
|
|
14
|
+
require 'taskjuggler/AppConfig'
|
|
14
15
|
require 'taskjuggler/Log'
|
|
15
|
-
require 'taskjuggler/
|
|
16
|
+
require 'taskjuggler/MessageHandler'
|
|
16
17
|
|
|
17
18
|
class TaskJuggler
|
|
18
19
|
|
|
19
20
|
module ProcessIntercomIface
|
|
20
21
|
|
|
22
|
+
include MessageHandler
|
|
23
|
+
|
|
21
24
|
# This function catches all unhandled exceptions in the passed block.
|
|
22
25
|
def trap
|
|
23
|
-
log = LogFile.instance
|
|
24
|
-
|
|
25
26
|
begin
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
MessageHandlerInstance.instance.trapSetup = true
|
|
28
|
+
res = yield
|
|
29
|
+
MessageHandlerInstance.instance.trapSetup = false
|
|
30
|
+
res
|
|
31
|
+
rescue => e
|
|
32
|
+
# Any exception here is a fata error. We try hard to terminate the DRb
|
|
33
|
+
# thread and then exit the program.
|
|
34
|
+
begin
|
|
35
|
+
fatal('pi_crash_trap', "#{e}\n#{e.backtrace.join("\n")}\n\n" +
|
|
36
|
+
"#{'*' * 79}\nYou have triggered a bug in " +
|
|
37
|
+
"#{AppConfig.softwareName} version #{AppConfig.version}!\n" +
|
|
38
|
+
"Please see the user manual on how to get this bug fixed!\n" +
|
|
39
|
+
"#{'*' * 79}\n")
|
|
40
|
+
rescue RuntimeError
|
|
41
|
+
@server.terminate
|
|
42
|
+
return false
|
|
43
|
+
end
|
|
32
44
|
end
|
|
33
45
|
end
|
|
34
46
|
|
|
@@ -54,12 +66,13 @@ class TaskJuggler
|
|
|
54
66
|
|
|
55
67
|
module ProcessIntercom
|
|
56
68
|
|
|
69
|
+
include MessageHandler
|
|
70
|
+
|
|
57
71
|
def initIntercom
|
|
58
72
|
# This is the authentication key that clients will need to provide to
|
|
59
73
|
# execute DRb methods.
|
|
60
74
|
@authKey = generateAuthKey
|
|
61
75
|
|
|
62
|
-
@log = LogFile.instance
|
|
63
76
|
# This flag will be set to true by DRb method calls to terminate the
|
|
64
77
|
# process.
|
|
65
78
|
@terminate = false
|
|
@@ -73,14 +86,14 @@ class TaskJuggler
|
|
|
73
86
|
end
|
|
74
87
|
|
|
75
88
|
def terminate
|
|
76
|
-
|
|
89
|
+
debug('', 'Terminating on external request')
|
|
77
90
|
@terminate = true
|
|
78
91
|
end
|
|
79
92
|
|
|
80
93
|
def connect(stdout, stderr, stdin, silent)
|
|
81
94
|
# Set the client lock.
|
|
82
95
|
@clientConnection.lock
|
|
83
|
-
|
|
96
|
+
debug('', 'Rerouting ProjectServer standard IO to client')
|
|
84
97
|
# Make sure that all output to STDOUT and STDERR is sent to the client.
|
|
85
98
|
# Input is read from the client STDIN. We save a copy of the old file
|
|
86
99
|
# handles so we can restore then later again.
|
|
@@ -90,18 +103,18 @@ class TaskJuggler
|
|
|
90
103
|
$stdout = stdout if stdout
|
|
91
104
|
$stderr = stderr if stdout
|
|
92
105
|
$stdin = stdin if stdin
|
|
93
|
-
|
|
106
|
+
debug('', 'IO is now routed to the client')
|
|
94
107
|
Log.silent = silent
|
|
95
108
|
true
|
|
96
109
|
end
|
|
97
110
|
|
|
98
111
|
def disconnect
|
|
99
|
-
|
|
112
|
+
debug('', 'Restoring IO')
|
|
100
113
|
Log.silent = true
|
|
101
114
|
$stdout = @stdout if @stdout
|
|
102
115
|
$stderr = @stderr if @stderr
|
|
103
116
|
$stdin = @stdin if @stdin
|
|
104
|
-
|
|
117
|
+
debug('', 'Standard IO has been restored')
|
|
105
118
|
# Release the client lock
|
|
106
119
|
@clientConnection.unlock
|
|
107
120
|
true
|
|
@@ -113,10 +126,11 @@ class TaskJuggler
|
|
|
113
126
|
|
|
114
127
|
def checkKey(authKey, command)
|
|
115
128
|
if authKey == @authKey
|
|
116
|
-
|
|
129
|
+
debug('', "Accepted authentication key for command '#{command}'")
|
|
117
130
|
else
|
|
118
|
-
|
|
119
|
-
|
|
131
|
+
warning('auth_key_rejected',
|
|
132
|
+
"Rejected wrong authentication key #{authKey}" +
|
|
133
|
+
"for command '#{command}'")
|
|
120
134
|
return false
|
|
121
135
|
end
|
|
122
136
|
true
|
|
@@ -126,7 +140,7 @@ class TaskJuggler
|
|
|
126
140
|
# client connection timer.
|
|
127
141
|
def restartTimer
|
|
128
142
|
@timeLock.synchronize do
|
|
129
|
-
|
|
143
|
+
debug('', 'Reseting client connection timer')
|
|
130
144
|
@timerStart = Time.new
|
|
131
145
|
end
|
|
132
146
|
end
|
|
@@ -156,9 +170,10 @@ class TaskJuggler
|
|
|
156
170
|
sleep 1
|
|
157
171
|
end
|
|
158
172
|
if timerExpired?
|
|
159
|
-
|
|
173
|
+
warning('drb_timeout_shutdown',
|
|
174
|
+
'Shutting down DRb server due to timeout')
|
|
160
175
|
else
|
|
161
|
-
|
|
176
|
+
debug('', 'Shutting down the DRb server')
|
|
162
177
|
end
|
|
163
178
|
DRb.stop_service
|
|
164
179
|
break
|
|
@@ -17,8 +17,8 @@ require 'drb'
|
|
|
17
17
|
require 'drb/acl'
|
|
18
18
|
require 'taskjuggler/daemon/Daemon'
|
|
19
19
|
require 'taskjuggler/daemon/ProjectServer'
|
|
20
|
-
require 'taskjuggler/daemon/WebServer'
|
|
21
20
|
require 'taskjuggler/TjTime'
|
|
21
|
+
require 'taskjuggler/MessageHandler'
|
|
22
22
|
|
|
23
23
|
class TaskJuggler
|
|
24
24
|
|
|
@@ -37,8 +37,9 @@ class TaskJuggler
|
|
|
37
37
|
# daemon.
|
|
38
38
|
class ProjectBroker < Daemon
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
include MessageHandler
|
|
41
|
+
|
|
42
|
+
attr_accessor :authKey, :port, :uriFile, :projectFiles, :logStdIO
|
|
42
43
|
|
|
43
44
|
def initialize
|
|
44
45
|
super
|
|
@@ -66,15 +67,6 @@ class TaskJuggler
|
|
|
66
67
|
# will be seperate set of files for each process.
|
|
67
68
|
@logStdIO = !@daemonize
|
|
68
69
|
|
|
69
|
-
# Reference to WEBrick object.
|
|
70
|
-
@webServer = nil
|
|
71
|
-
|
|
72
|
-
# Port used by the web server
|
|
73
|
-
@webServerPort = 8080
|
|
74
|
-
|
|
75
|
-
# True if web server should be activated
|
|
76
|
-
@enableWebServer = false
|
|
77
|
-
|
|
78
70
|
# This flag will be set to true to terminate the daemon.
|
|
79
71
|
@terminate = false
|
|
80
72
|
end
|
|
@@ -83,7 +75,7 @@ class TaskJuggler
|
|
|
83
75
|
# To ensure a certain level of security, the user must provide an
|
|
84
76
|
# authentication key to authenticate the client to this server.
|
|
85
77
|
unless @authKey
|
|
86
|
-
|
|
78
|
+
error('pb_no_auth_key', <<'EOT'
|
|
87
79
|
You must set an authentication key in the configuration file. Create a file
|
|
88
80
|
named .taskjugglerrc or taskjuggler.rc that contains at least the following
|
|
89
81
|
lines. Replace 'your_secret_key' with some random character sequence.
|
|
@@ -96,18 +88,7 @@ EOT
|
|
|
96
88
|
|
|
97
89
|
# In daemon mode, we fork twice and only the 2nd child continues here.
|
|
98
90
|
super()
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
if @enableWebServer
|
|
102
|
-
begin
|
|
103
|
-
# The web server must be started before we turn SAFE mode on.
|
|
104
|
-
@webServer = WebServer.new(self, @webServerPort)
|
|
105
|
-
@log.info("TaskJuggler web server is listening on port " +
|
|
106
|
-
"#{@webServerPort}")
|
|
107
|
-
rescue
|
|
108
|
-
@log.fatal("Cannot start web server: #{$!}")
|
|
109
|
-
end
|
|
110
|
-
end
|
|
91
|
+
debug('', "Starting project broker")
|
|
111
92
|
|
|
112
93
|
# Setup a DRb server to handle the incomming requests from the clients.
|
|
113
94
|
brokerIface = ProjectBrokerIface.new(self)
|
|
@@ -116,9 +97,9 @@ EOT
|
|
|
116
97
|
DRb.install_acl(ACL.new(%w[ deny all
|
|
117
98
|
allow 127.0.0.1 ]))
|
|
118
99
|
@uri = DRb.start_service("druby://127.0.0.1:#{@port}", brokerIface).uri
|
|
119
|
-
|
|
100
|
+
info('daemon_uri', "TaskJuggler daemon is listening on #{@uri}")
|
|
120
101
|
rescue
|
|
121
|
-
|
|
102
|
+
error('port_in_use', "Cannot listen on port #{@port}: #{$!}")
|
|
122
103
|
end
|
|
123
104
|
|
|
124
105
|
if @port == 0 && @uriFile
|
|
@@ -127,7 +108,7 @@ EOT
|
|
|
127
108
|
begin
|
|
128
109
|
File.open(@uriFile, 'w') { |f| f.write @uri }
|
|
129
110
|
rescue
|
|
130
|
-
|
|
111
|
+
error('cannot_write_uri', "Cannot write URI file #{@uriFile}: #{$!}")
|
|
131
112
|
end
|
|
132
113
|
end
|
|
133
114
|
|
|
@@ -141,19 +122,19 @@ EOT
|
|
|
141
122
|
# some other work asynchronously.
|
|
142
123
|
startHousekeeping
|
|
143
124
|
|
|
144
|
-
|
|
145
|
-
DRb.
|
|
125
|
+
debug('', 'Shutting down ProjectBroker DRb server')
|
|
126
|
+
DRb.stop_service
|
|
146
127
|
|
|
147
128
|
# If we have created a URI file, we need to delete it again.
|
|
148
129
|
if @port == 0 && @uriFile
|
|
149
130
|
begin
|
|
150
131
|
File.delete(@uriFile)
|
|
151
132
|
rescue
|
|
152
|
-
|
|
133
|
+
error('cannot_delete_uri', "Cannot delete URI file .tj3d.uri: #{$!}")
|
|
153
134
|
end
|
|
154
135
|
end
|
|
155
136
|
|
|
156
|
-
|
|
137
|
+
info('daemon_terminated', 'TaskJuggler daemon terminated')
|
|
157
138
|
end
|
|
158
139
|
|
|
159
140
|
# All remote commands must provide the proper authentication key. Usually
|
|
@@ -161,10 +142,11 @@ EOT
|
|
|
161
142
|
# configuration file.
|
|
162
143
|
def checkKey(authKey, command)
|
|
163
144
|
if authKey == @authKey
|
|
164
|
-
|
|
145
|
+
debug('', "Accepted authentication key for command '#{command}'")
|
|
165
146
|
else
|
|
166
|
-
|
|
167
|
-
|
|
147
|
+
warning('wrong_auth_key',
|
|
148
|
+
"Rejected wrong authentication key '#{authKey}' " +
|
|
149
|
+
"for command '#{command}'")
|
|
168
150
|
return false
|
|
169
151
|
end
|
|
170
152
|
true
|
|
@@ -172,7 +154,7 @@ EOT
|
|
|
172
154
|
|
|
173
155
|
# This command will initiate the termination of the daemon.
|
|
174
156
|
def stop
|
|
175
|
-
|
|
157
|
+
debug('', 'Terminating on client request')
|
|
176
158
|
|
|
177
159
|
# Shut down the web server if we've started one.
|
|
178
160
|
if @webServer
|
|
@@ -216,7 +198,7 @@ EOT
|
|
|
216
198
|
# associated to. Just use a large enough random number.
|
|
217
199
|
tag = rand(9999999999999)
|
|
218
200
|
|
|
219
|
-
|
|
201
|
+
debug('', "Pushing #{tag} to load Queue")
|
|
220
202
|
@projectsToLoad.push(tag)
|
|
221
203
|
|
|
222
204
|
# Now we have to wait until the project shows up in the @projects
|
|
@@ -236,23 +218,23 @@ EOT
|
|
|
236
218
|
sleep 0.1 unless pr
|
|
237
219
|
end
|
|
238
220
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
221
|
+
debug('', "Found tag #{tag} in list of loaded projects with URI " +
|
|
222
|
+
"#{pr.uri}")
|
|
223
|
+
|
|
224
|
+
res = false
|
|
243
225
|
|
|
244
226
|
# Open a DRb connection to the ProjectServer process
|
|
245
227
|
begin
|
|
246
228
|
projectServer = DRbObject.new(nil, pr.uri)
|
|
247
229
|
rescue
|
|
248
|
-
|
|
230
|
+
warning('pb_cannot_get_ps', "Can't get ProjectServer object: #{$!}")
|
|
249
231
|
return false
|
|
250
232
|
end
|
|
251
233
|
begin
|
|
252
234
|
# Hook up IO from requestor to the ProjectServer process.
|
|
253
235
|
projectServer.connect(pr.authKey, stdOut, stdErr, stdIn, silent)
|
|
254
236
|
rescue
|
|
255
|
-
|
|
237
|
+
warning('pb_cannot_connect_io', "Can't connect IO: #{$!}")
|
|
256
238
|
return false
|
|
257
239
|
end
|
|
258
240
|
|
|
@@ -261,7 +243,7 @@ EOT
|
|
|
261
243
|
begin
|
|
262
244
|
res = projectServer.loadProject(pr.authKey, [ cwd, *args ])
|
|
263
245
|
rescue
|
|
264
|
-
|
|
246
|
+
warning('pb_load_failed', "Loading of project failed: #{$!}")
|
|
265
247
|
return false
|
|
266
248
|
end
|
|
267
249
|
|
|
@@ -269,7 +251,7 @@ EOT
|
|
|
269
251
|
begin
|
|
270
252
|
projectServer.disconnect(pr.authKey)
|
|
271
253
|
rescue
|
|
272
|
-
|
|
254
|
+
warning('pb_cannot_disconnect_io', "Can't disconnect IO: #{$!}")
|
|
273
255
|
return false
|
|
274
256
|
end
|
|
275
257
|
|
|
@@ -278,7 +260,8 @@ EOT
|
|
|
278
260
|
|
|
279
261
|
def removeProject(indexOrId)
|
|
280
262
|
@projects.synchronize do
|
|
281
|
-
# Find all projects with the IDs in indexOrId and mark them as
|
|
263
|
+
# Find all projects with the IDs in indexOrId and mark them as
|
|
264
|
+
# :obsolete.
|
|
282
265
|
if /^[0-9]$/.match(indexOrId)
|
|
283
266
|
index = indexOrId.to_i - 1
|
|
284
267
|
if index >= 0 && index < @projects.length
|
|
@@ -315,7 +298,7 @@ EOT
|
|
|
315
298
|
end
|
|
316
299
|
|
|
317
300
|
if project.nil?
|
|
318
|
-
|
|
301
|
+
debug('', "No project with ID #{projectId} found")
|
|
319
302
|
return [ nil, nil ]
|
|
320
303
|
end
|
|
321
304
|
[ project.uri, project.authKey ]
|
|
@@ -371,7 +354,7 @@ EOT
|
|
|
371
354
|
# Don't accept updates for already obsolete entries.
|
|
372
355
|
next if project.state == :obsolete
|
|
373
356
|
|
|
374
|
-
|
|
357
|
+
debug('', "Updating state for #{id} to #{state}")
|
|
375
358
|
# Only update the record that has the matching key
|
|
376
359
|
if project.authKey == projectKey
|
|
377
360
|
project.id = id if id
|
|
@@ -385,7 +368,7 @@ EOT
|
|
|
385
368
|
@projects.each do |p|
|
|
386
369
|
if p != project && p.id == id
|
|
387
370
|
p.state = :obsolete
|
|
388
|
-
|
|
371
|
+
debug('', "Marking entry with ID #{id} as obsolete")
|
|
389
372
|
end
|
|
390
373
|
end
|
|
391
374
|
project.readySince = TjTime.new
|
|
@@ -409,64 +392,64 @@ EOT
|
|
|
409
392
|
private
|
|
410
393
|
|
|
411
394
|
def startHousekeeping
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
elsif p.state == :failed
|
|
434
|
-
# Start removal of entries that didn't parse.
|
|
435
|
-
p.state = :obsolete
|
|
436
|
-
end
|
|
395
|
+
begin
|
|
396
|
+
cntr = 0
|
|
397
|
+
loop do
|
|
398
|
+
if @terminate
|
|
399
|
+
# Give the caller a chance to properly terminate the connection.
|
|
400
|
+
sleep 0.5
|
|
401
|
+
break
|
|
402
|
+
elsif !@projectsToLoad.empty?
|
|
403
|
+
loadProject(@projectsToLoad.pop)
|
|
404
|
+
else
|
|
405
|
+
# Send termination command to all obsolute ProjectServer
|
|
406
|
+
# objects. To minimize the locking of @projects we collect the
|
|
407
|
+
# obsolete items first.
|
|
408
|
+
termList = []
|
|
409
|
+
@projects.synchronize do
|
|
410
|
+
@projects.each do |p|
|
|
411
|
+
if p.state == :obsolete
|
|
412
|
+
termList << p
|
|
413
|
+
elsif p.state == :failed
|
|
414
|
+
# Start removal of entries that didn't parse.
|
|
415
|
+
p.state = :obsolete
|
|
437
416
|
end
|
|
438
417
|
end
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
418
|
+
end
|
|
419
|
+
# And then send them a termination command.
|
|
420
|
+
termList.each { |p| p.terminateServer }
|
|
421
|
+
|
|
422
|
+
# Check every 10 seconds that the ProjectServer processes are
|
|
423
|
+
# still alive. If not, remove them from the list.
|
|
424
|
+
if (cntr += 1) > 10
|
|
425
|
+
@projects.synchronize do
|
|
426
|
+
@projects.each do |p|
|
|
427
|
+
unless p.ping
|
|
428
|
+
termList << p unless termList.include?(p)
|
|
450
429
|
end
|
|
451
430
|
end
|
|
452
|
-
cntr = 0
|
|
453
431
|
end
|
|
432
|
+
cntr = 0
|
|
433
|
+
end
|
|
454
434
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
435
|
+
# The housekeeping thread rarely needs to so something. Make
|
|
436
|
+
# sure it's sleeping most of the time.
|
|
437
|
+
sleep 1
|
|
458
438
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
end
|
|
439
|
+
# Remove the obsolete records from the @projects list.
|
|
440
|
+
@projects.synchronize do
|
|
441
|
+
@projects.delete_if { |p| termList.include?(p) }
|
|
463
442
|
end
|
|
464
443
|
end
|
|
465
|
-
rescue
|
|
466
|
-
$stderr.print $!.to_s
|
|
467
|
-
$stderr.print $!.backtrace.join("\n")
|
|
468
|
-
@log.fatal("ProjectBroker housekeeping error: #{$!}")
|
|
469
444
|
end
|
|
445
|
+
rescue => exception
|
|
446
|
+
# TjRuntimeError exceptions are simply passed through.
|
|
447
|
+
if exception.is_a?(TjRuntimeError)
|
|
448
|
+
raise TjRuntimeError, $!
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
fatal('pb_housekeeping_error',
|
|
452
|
+
"ProjectBroker housekeeping error: #{$!}")
|
|
470
453
|
end
|
|
471
454
|
end
|
|
472
455
|
|
|
@@ -475,11 +458,11 @@ EOT
|
|
|
475
458
|
tag = rand(9999999999999)
|
|
476
459
|
project = tagOrProject
|
|
477
460
|
# The 2nd element of the Array is the *.tjp file name.
|
|
478
|
-
|
|
461
|
+
debug('', "Loading project #{tagOrProject[1]} with tag #{tag}")
|
|
479
462
|
else
|
|
480
463
|
tag = tagOrProject
|
|
481
464
|
project = nil
|
|
482
|
-
|
|
465
|
+
debug('', "Loading project for tag #{tag}")
|
|
483
466
|
end
|
|
484
467
|
pr = ProjectRecord.new(tag)
|
|
485
468
|
ps = ProjectServer.new(@authKey, project, @logStdIO)
|
|
@@ -500,6 +483,8 @@ EOT
|
|
|
500
483
|
# these methods for remote access.
|
|
501
484
|
class ProjectBrokerIface
|
|
502
485
|
|
|
486
|
+
include MessageHandler
|
|
487
|
+
|
|
503
488
|
def initialize(broker)
|
|
504
489
|
@broker = broker
|
|
505
490
|
end
|
|
@@ -517,15 +502,25 @@ EOT
|
|
|
517
502
|
|
|
518
503
|
# This function catches all unhandled exceptions in the passed block.
|
|
519
504
|
def trap
|
|
520
|
-
log = LogFile.instance
|
|
521
|
-
|
|
522
505
|
begin
|
|
523
506
|
yield
|
|
524
|
-
rescue
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
507
|
+
rescue => e
|
|
508
|
+
# TjRuntimeError exceptions are simply passed through.
|
|
509
|
+
if e.is_a?(TjRuntimeError)
|
|
510
|
+
raise TjRuntimeError, $!
|
|
511
|
+
end
|
|
512
|
+
|
|
513
|
+
# Any exception here is a fata error. We try hard to terminate the DRb
|
|
514
|
+
# thread and then exit the program.
|
|
515
|
+
begin
|
|
516
|
+
fatal('pb_crash_trap', "#{e}\n#{e.backtrace.join("\n")}\n\n" +
|
|
517
|
+
"#{'*' * 79}\nYou have triggered a bug in " +
|
|
518
|
+
"#{AppConfig.softwareName} version #{AppConfig.version}!\n" +
|
|
519
|
+
"Please see the user manual on how to get this bug fixed!\n" +
|
|
520
|
+
"#{'*' * 79}\n")
|
|
521
|
+
rescue RuntimeError
|
|
522
|
+
@broker.stop
|
|
523
|
+
end
|
|
529
524
|
end
|
|
530
525
|
end
|
|
531
526
|
|
|
@@ -549,11 +544,24 @@ EOT
|
|
|
549
544
|
when :update
|
|
550
545
|
@broker.update
|
|
551
546
|
else
|
|
552
|
-
|
|
547
|
+
fatal('unknown_command', 'Unknown command #{cmd} called')
|
|
553
548
|
end
|
|
554
549
|
end
|
|
555
550
|
end
|
|
556
551
|
|
|
552
|
+
def getProjectList(authKey)
|
|
553
|
+
return false unless @broker.checkKey(authKey, 'getProjectList')
|
|
554
|
+
|
|
555
|
+
trap { @broker.getProjectList }
|
|
556
|
+
end
|
|
557
|
+
|
|
558
|
+
def getProject(authKey, id)
|
|
559
|
+
return false unless @broker.checkKey(authKey, 'getProject')
|
|
560
|
+
|
|
561
|
+
debug('', "PID: #{id} Class: #{id.class}")
|
|
562
|
+
trap { @broker.getProject(id) }
|
|
563
|
+
end
|
|
564
|
+
|
|
557
565
|
def updateState(authKey, projectKey, id, status, modified)
|
|
558
566
|
return false unless @broker.checkKey(authKey, 'updateState')
|
|
559
567
|
|
|
@@ -566,6 +574,8 @@ EOT
|
|
|
566
574
|
# one entry for each project in the @projects list.
|
|
567
575
|
class ProjectRecord < Monitor
|
|
568
576
|
|
|
577
|
+
include MessageHandler
|
|
578
|
+
|
|
569
579
|
attr_accessor :authKey, :uri, :files, :id, :state, :readySince, :modified,
|
|
570
580
|
:reloading
|
|
571
581
|
attr_reader :tag
|
|
@@ -592,19 +602,18 @@ EOT
|
|
|
592
602
|
# True if the reload has already been triggered.
|
|
593
603
|
@reloading = false
|
|
594
604
|
|
|
595
|
-
@log = LogFile.instance
|
|
596
605
|
@projectServer = nil
|
|
597
606
|
end
|
|
598
607
|
|
|
599
608
|
def ping
|
|
600
609
|
return true unless @uri
|
|
601
610
|
|
|
602
|
-
|
|
611
|
+
debug('', "Sending ping to ProjectServer #{@uri}")
|
|
603
612
|
begin
|
|
604
613
|
@projectServer = DRbObject.new(nil, @uri) unless @projectServer
|
|
605
614
|
@projectServer.ping(@authKey)
|
|
606
615
|
rescue
|
|
607
|
-
|
|
616
|
+
warning('ping_failed', "Ping failed: #{$!}")
|
|
608
617
|
return false
|
|
609
618
|
end
|
|
610
619
|
true
|
|
@@ -615,11 +624,12 @@ EOT
|
|
|
615
624
|
return unless @uri
|
|
616
625
|
|
|
617
626
|
begin
|
|
618
|
-
|
|
627
|
+
debug('', "Sending termination request to ProjectServer #{@uri}")
|
|
619
628
|
@projectServer = DRbObject.new(nil, @uri) unless @projectServer
|
|
620
629
|
@projectServer.terminate(@authKey)
|
|
621
630
|
rescue
|
|
622
|
-
|
|
631
|
+
error('proj_serv_term_failed',
|
|
632
|
+
"Termination of ProjectServer failed: #{$!}")
|
|
623
633
|
end
|
|
624
634
|
@uri = nil
|
|
625
635
|
end
|