This commit is contained in:
1
source/csla10/CSLA.BatchQueue/.cvsignore
Normal file
1
source/csla10/CSLA.BatchQueue/.cvsignore
Normal file
@@ -0,0 +1 @@
|
||||
CSLA.BatchQueue.xml
|
||||
32
source/csla10/CSLA.BatchQueue/AssemblyInfo.vb
Normal file
32
source/csla10/CSLA.BatchQueue/AssemblyInfo.vb
Normal file
@@ -0,0 +1,32 @@
|
||||
Imports System
|
||||
Imports System.Reflection
|
||||
Imports System.Runtime.InteropServices
|
||||
|
||||
' General Information about an assembly is controlled through the following
|
||||
' set of attributes. Change these attribute values to modify the information
|
||||
' associated with an assembly.
|
||||
|
||||
' Review the values of the assembly attributes
|
||||
|
||||
<Assembly: AssemblyTitle("CSLA.BatchQueue")>
|
||||
<Assembly: AssemblyDescription("CSLA .NET framework")>
|
||||
<Assembly: AssemblyCompany("Rockford Lhotka")>
|
||||
<Assembly: AssemblyProduct("Expert One-on-One VB.NET Business Objects")>
|
||||
<Assembly: AssemblyCopyright("Copyright 2003 Rockford Lhotka. All rights reserved.")>
|
||||
<Assembly: AssemblyTrademark("")>
|
||||
<Assembly: CLSCompliant(True)>
|
||||
|
||||
'The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
<Assembly: Guid("EC45E25E-E411-4477-95FE-1F10004502E0")>
|
||||
|
||||
' Version information for an assembly consists of the following four values:
|
||||
'
|
||||
' Major Version
|
||||
' Minor Version
|
||||
' Build Number
|
||||
' Revision
|
||||
'
|
||||
' You can specify all the values or you can default the Build and Revision Numbers
|
||||
' by using the '*' as shown below:
|
||||
|
||||
<Assembly: AssemblyVersion("1.3.*")>
|
||||
49
source/csla10/CSLA.BatchQueue/BatchEntries.vb
Normal file
49
source/csla10/CSLA.BatchQueue/BatchEntries.vb
Normal file
@@ -0,0 +1,49 @@
|
||||
Imports System.Messaging
|
||||
Imports System.Runtime.Serialization.Formatters.Binary
|
||||
|
||||
''' <summary>
|
||||
''' Contains a list of holding, pending and active batch
|
||||
''' queue entries.
|
||||
''' </summary>
|
||||
<Serializable()> _
|
||||
Public Class BatchEntries
|
||||
Inherits CollectionBase
|
||||
|
||||
''' <summary>
|
||||
''' Returns a reference to an object with information about
|
||||
''' a specific batch queue entry.
|
||||
''' </summary>
|
||||
Default Public ReadOnly Property Entry(ByVal index As Integer) As BatchEntryInfo
|
||||
Get
|
||||
Return CType(list.Item(index), BatchEntryInfo)
|
||||
End Get
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' Returns a reference to an object with information about
|
||||
''' a specific batch queue entry.
|
||||
''' </summary>
|
||||
''' <param name="ID">The ID value of the entry to return.</param>
|
||||
Default Public ReadOnly Property Entry(ByVal ID As Guid) As BatchEntryInfo
|
||||
Get
|
||||
Dim obj As BatchEntryInfo
|
||||
|
||||
For Each obj In list
|
||||
If obj.ID.Equals(ID) Then
|
||||
Return obj
|
||||
End If
|
||||
Next
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Friend Sub New()
|
||||
|
||||
' prevent direct creation
|
||||
|
||||
End Sub
|
||||
|
||||
Friend Sub Add(ByVal Value As BatchEntryInfo)
|
||||
list.Add(Value)
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
225
source/csla10/CSLA.BatchQueue/BatchEntry.vb
Normal file
225
source/csla10/CSLA.BatchQueue/BatchEntry.vb
Normal file
@@ -0,0 +1,225 @@
|
||||
Imports System.Security.Principal
|
||||
Imports System.Configuration
|
||||
|
||||
''' <summary>
|
||||
'''
|
||||
''' </summary>
|
||||
Namespace Server
|
||||
|
||||
''' <summary>
|
||||
''' A batch queue entry.
|
||||
''' </summary>
|
||||
''' <remarks>
|
||||
''' Each batch queue entry consists of basic information about
|
||||
''' the entry, a Principal object (if you are using CSLA .NET
|
||||
''' security), the actual worker object containing the code
|
||||
''' to be run and an optional state object containing arbitrary
|
||||
''' state data.
|
||||
''' </remarks>
|
||||
<Serializable()> _
|
||||
Public NotInheritable Class BatchEntry
|
||||
Private mInfo As New BatchEntryInfo
|
||||
Private mPrincipal As IPrincipal = GetPrincipal()
|
||||
Private mWorker As IBatchEntry
|
||||
Private mState As Object
|
||||
|
||||
''' <summary>
|
||||
''' Returns a reference to the object containing information
|
||||
''' about this batch entry.
|
||||
''' </summary>
|
||||
Public ReadOnly Property Info() As BatchEntryInfo
|
||||
Get
|
||||
Return mInfo
|
||||
End Get
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' Returns a reference to the
|
||||
''' <see cref="T:CSLA.Security.BusinessPrincipal" />
|
||||
''' object for the user that submitted this entry.
|
||||
''' </summary>
|
||||
Public ReadOnly Property Principal() As IPrincipal
|
||||
Get
|
||||
Return mPrincipal
|
||||
End Get
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' Returns a reference to the worker object that
|
||||
''' contains the code which is to be executed as
|
||||
''' a batch process.
|
||||
''' </summary>
|
||||
Public Property Entry() As IBatchEntry
|
||||
Get
|
||||
Return mWorker
|
||||
End Get
|
||||
Set(ByVal Value As IBatchEntry)
|
||||
mWorker = Value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' Returns a reference to the optional state object.
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property State() As Object
|
||||
Get
|
||||
Return mState
|
||||
End Get
|
||||
Set(ByVal Value As Object)
|
||||
mState = Value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
#Region " Batch execution "
|
||||
|
||||
' this will run in a background thread in the
|
||||
' thread pool
|
||||
Friend Sub Execute(ByVal State As Object)
|
||||
|
||||
|
||||
Dim oldPrincipal As IPrincipal
|
||||
|
||||
Try
|
||||
' set this thread's principal to our user
|
||||
oldPrincipal = Threading.Thread.CurrentPrincipal
|
||||
SetPrincipal(mPrincipal)
|
||||
|
||||
Try
|
||||
' now run the user's code
|
||||
mWorker.Execute(mState)
|
||||
|
||||
Dim sb As New Text.StringBuilder()
|
||||
With sb
|
||||
.Append("Batch job completed")
|
||||
.Append(vbCrLf)
|
||||
.AppendFormat("Batch job: {0}", Me.ToString)
|
||||
.Append(vbCrLf)
|
||||
.AppendFormat("Job object: {0}", CType(mWorker, Object).ToString)
|
||||
.Append(vbCrLf)
|
||||
End With
|
||||
|
||||
System.Diagnostics.EventLog.WriteEntry( _
|
||||
BatchQueueService.Name, sb.ToString, EventLogEntryType.Information)
|
||||
|
||||
Catch ex As Exception
|
||||
Dim sb As New Text.StringBuilder()
|
||||
With sb
|
||||
.Append("Batch job failed due to execution error")
|
||||
.Append(vbCrLf)
|
||||
.AppendFormat("Batch job: {0}", Me.ToString)
|
||||
.Append(vbCrLf)
|
||||
.AppendFormat("Job object: {0}", CType(mWorker, Object).ToString)
|
||||
.Append(vbCrLf)
|
||||
.Append(ex.ToString)
|
||||
End With
|
||||
|
||||
System.Diagnostics.EventLog.WriteEntry( _
|
||||
BatchQueueService.Name, sb.ToString, EventLogEntryType.Warning)
|
||||
End Try
|
||||
|
||||
Finally
|
||||
Server.BatchQueueService.Deactivate(Me)
|
||||
' reset the thread's principal object
|
||||
Threading.Thread.CurrentPrincipal = oldPrincipal
|
||||
End Try
|
||||
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
|
||||
#Region " System.Object overrides "
|
||||
|
||||
Public Overrides Function ToString() As String
|
||||
|
||||
Return mInfo.ToString
|
||||
|
||||
End Function
|
||||
|
||||
Public Overloads Function Equals(ByVal Entry As BatchEntry) As Boolean
|
||||
|
||||
Return mInfo.Equals(Entry.Info)
|
||||
|
||||
End Function
|
||||
|
||||
Public Overrides Function GetHashCode() As Integer
|
||||
|
||||
Return mInfo.GetHashCode
|
||||
|
||||
End Function
|
||||
|
||||
#End Region
|
||||
|
||||
#Region " Constructors "
|
||||
|
||||
Friend Sub New(ByVal Entry As IBatchEntry)
|
||||
|
||||
mWorker = Entry
|
||||
|
||||
End Sub
|
||||
|
||||
Friend Sub New(ByVal Entry As IBatchEntry, ByVal State As Object)
|
||||
|
||||
mWorker = Entry
|
||||
mState = State
|
||||
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
|
||||
#Region " Security "
|
||||
|
||||
Private Function AUTHENTICATION() As String
|
||||
Return ConfigurationSettings.AppSettings("Authentication")
|
||||
End Function
|
||||
|
||||
Private Function GetPrincipal() As System.Security.Principal.IPrincipal
|
||||
If AUTHENTICATION() = "Windows" Then
|
||||
' Windows integrated security
|
||||
Return Nothing
|
||||
|
||||
Else
|
||||
' we assume using the CSLA framework security
|
||||
Return System.Threading.Thread.CurrentPrincipal
|
||||
End If
|
||||
End Function
|
||||
|
||||
Private Sub SetPrincipal(ByVal Principal As Object)
|
||||
If AUTHENTICATION() = "Windows" Then
|
||||
' when using integrated security, Principal must be Nothing
|
||||
' and we need to set our policy to use the Windows principal
|
||||
If Principal Is Nothing Then
|
||||
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal)
|
||||
Exit Sub
|
||||
|
||||
Else
|
||||
Throw New System.Security.SecurityException("No principal object should be passed to DataPortal when using Windows integrated security")
|
||||
End If
|
||||
End If
|
||||
|
||||
' we expect Principal to be of type BusinessPrincipal, but
|
||||
' we can't enforce that since it causes a circular reference
|
||||
' with the business library so instead we must use type Object
|
||||
' for the parameter, so here we do a check on the type of the
|
||||
' parameter
|
||||
If Principal.ToString = "CSLA.Security.BusinessPrincipal" Then
|
||||
' see if our current principal is
|
||||
' different from the caller's principal
|
||||
If Not ReferenceEquals(Principal, System.Threading.Thread.CurrentPrincipal) Then
|
||||
' the caller had a different principal, so change ours to
|
||||
' match the caller's so all our objects use the caller's
|
||||
' security
|
||||
System.Threading.Thread.CurrentPrincipal = CType(Principal, IPrincipal)
|
||||
End If
|
||||
|
||||
Else
|
||||
Throw New System.Security.SecurityException("Principal must be of type BusinessPrincipal, not " & Principal.ToString)
|
||||
End If
|
||||
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
|
||||
End Class
|
||||
|
||||
End Namespace
|
||||
185
source/csla10/CSLA.BatchQueue/BatchEntryInfo.vb
Normal file
185
source/csla10/CSLA.BatchQueue/BatchEntryInfo.vb
Normal file
@@ -0,0 +1,185 @@
|
||||
Imports System.Environment
|
||||
|
||||
''' <summary>
|
||||
''' Values indicating the status of a batch queue entry.
|
||||
''' </summary>
|
||||
Public Enum BatchEntryStatus
|
||||
Pending
|
||||
Holding
|
||||
Active
|
||||
End Enum
|
||||
|
||||
''' <summary>
|
||||
''' Contains information about a batch queue entry.
|
||||
''' </summary>
|
||||
''' <remarks>
|
||||
''' This object contains information about batch entry including
|
||||
''' when it was submitted, the user that submitted the job and
|
||||
''' which machine the user was using at the time. It also contains
|
||||
''' the job's priority, status and the optional date/time until
|
||||
''' which the job should be held until it is run.
|
||||
''' </remarks>
|
||||
<Serializable()> _
|
||||
Public Class BatchEntryInfo
|
||||
|
||||
Private mID As Guid = Guid.NewGuid
|
||||
Private mSubmitted As Date = Now
|
||||
Private mUser As String = System.Environment.UserName
|
||||
Private mMachine As String = System.Environment.MachineName
|
||||
Private mPriority As Messaging.MessagePriority = Messaging.MessagePriority.Normal
|
||||
Private mMsgID As String
|
||||
Private mHoldUntil As Date = Date.MinValue
|
||||
Private mStatus As BatchEntryStatus = BatchEntryStatus.Pending
|
||||
|
||||
''' <summary>
|
||||
''' Returns the unique ID value for this batch entry.
|
||||
''' </summary>
|
||||
Public ReadOnly Property ID() As Guid
|
||||
Get
|
||||
Return mID
|
||||
End Get
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' Returns the date and time that the batch entry
|
||||
''' was submitted.
|
||||
''' </summary>
|
||||
Public ReadOnly Property Submitted() As Date
|
||||
Get
|
||||
Return mSubmitted
|
||||
End Get
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' Returns the Windows user id of the user that
|
||||
''' was logged into the workstation when the job
|
||||
''' was submitted.
|
||||
''' </summary>
|
||||
Public ReadOnly Property User() As String
|
||||
Get
|
||||
Return mUser
|
||||
End Get
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' Returns the name of the workstation from
|
||||
''' which this job was submitted.
|
||||
''' </summary>
|
||||
Public ReadOnly Property Machine() As String
|
||||
Get
|
||||
Return mMachine
|
||||
End Get
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' Returns the priority of this batch entry.
|
||||
''' </summary>
|
||||
''' <remarks>
|
||||
''' The priority values flow from System.Messaging and
|
||||
''' the priority is used by MSMQ to order the entries
|
||||
''' in the queue.
|
||||
''' </remarks>
|
||||
Public Property Priority() As Messaging.MessagePriority
|
||||
Get
|
||||
Return mPriority
|
||||
End Get
|
||||
Set(ByVal Value As Messaging.MessagePriority)
|
||||
mPriority = Value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' Returns the MSMQ message ID of the batch entry.
|
||||
''' </summary>
|
||||
''' <remarks>
|
||||
''' This value is only valid after the batch entry
|
||||
''' has been submitted to the queue.
|
||||
''' </remarks>
|
||||
Public ReadOnly Property MessageID() As String
|
||||
Get
|
||||
Return mMsgID
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Friend Sub SetMessageID(ByVal ID As String)
|
||||
mMsgID = ID
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Returns the date and time until which the
|
||||
''' batch entry will be held before it can be run.
|
||||
''' </summary>
|
||||
''' <remarks>
|
||||
''' This value is optional. If it was provided, the batch
|
||||
''' entry will be held until this date/time. At this date/time,
|
||||
''' the entry will switch from Holding status to Pending
|
||||
''' status and will be queued based on its priority along
|
||||
''' with all other Pending entries.
|
||||
''' </remarks>
|
||||
Public Property HoldUntil() As Date
|
||||
Get
|
||||
Return mHoldUntil
|
||||
End Get
|
||||
Set(ByVal Value As Date)
|
||||
mHoldUntil = Value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' Returns the status of the batch entry.
|
||||
''' </summary>
|
||||
''' <remarks>
|
||||
''' <para>
|
||||
''' If the job is Holding, it means that the job
|
||||
''' won't run until the data/time specified by
|
||||
''' <see cref="P:CSLA.BatchQueue.BatchEntryInfo.HoldUntil" />.
|
||||
''' </para><para>
|
||||
''' If the job is Pending, it means that the job
|
||||
''' will run as soon as possible, but that the queue
|
||||
''' is busy. Pending entries are run in priority order based
|
||||
''' on <see cref="P:CSLA.BatchQueue.BatchEntryInfo.Priority" />.
|
||||
''' </para><para>
|
||||
''' If the job is Active, it means that the job is
|
||||
''' currently being executed on the server.
|
||||
''' </para>
|
||||
''' </remarks>
|
||||
Public ReadOnly Property Status() As BatchEntryStatus
|
||||
Get
|
||||
If mHoldUntil > Now AndAlso mStatus = BatchEntryStatus.Pending Then
|
||||
Return BatchEntryStatus.Holding
|
||||
|
||||
Else
|
||||
Return mStatus
|
||||
End If
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Friend Sub SetStatus(ByVal Status As BatchEntryStatus)
|
||||
|
||||
mStatus = Status
|
||||
|
||||
End Sub
|
||||
|
||||
#Region " System.Object overrides "
|
||||
|
||||
Public Overrides Function ToString() As String
|
||||
|
||||
Return mUser & "@" & mMachine & ":" & mID.ToString
|
||||
|
||||
End Function
|
||||
|
||||
Public Overloads Function Equals(ByVal Info As BatchEntryInfo) As Boolean
|
||||
|
||||
Return mID.Equals(Info.ID)
|
||||
|
||||
End Function
|
||||
|
||||
Public Overrides Function GetHashCode() As Integer
|
||||
|
||||
Return mID.GetHashCode
|
||||
|
||||
End Function
|
||||
|
||||
#End Region
|
||||
|
||||
End Class
|
||||
97
source/csla10/CSLA.BatchQueue/BatchJobRequest.vb
Normal file
97
source/csla10/CSLA.BatchQueue/BatchJobRequest.vb
Normal file
@@ -0,0 +1,97 @@
|
||||
''' <summary>
|
||||
''' A helper object used to execute a specified class
|
||||
''' from a specified DLL on the server.
|
||||
''' </summary>
|
||||
''' <remarks>
|
||||
''' <para>
|
||||
''' A worker object can be provided directly by the client
|
||||
''' workstation. In that case, the worker object is passed
|
||||
''' by value to the server where it is executed. The drawback
|
||||
''' to such an approach is that the worker assembly must be
|
||||
''' installed on both client and server.
|
||||
''' </para><para>
|
||||
''' BatchJobRequest is a worker object that specifies the
|
||||
''' type and assembly name of a class on the server. When
|
||||
''' this job is run, it dynamically creates an instance of
|
||||
''' the specified class and executes it on the server. This
|
||||
''' means that the actual worker assembly needs to be installed
|
||||
''' only on the server, not on the client.
|
||||
''' </para>
|
||||
''' </remarks>
|
||||
<Serializable()> _
|
||||
Public Class BatchJobRequest
|
||||
|
||||
Implements IBatchEntry
|
||||
|
||||
Private mAssembly As String = ""
|
||||
Private mType As String = ""
|
||||
|
||||
''' <summary>
|
||||
''' Creates a new object, specifying the type and assembly
|
||||
''' of the actual worker object.
|
||||
''' </summary>
|
||||
''' <param name="Type">The class name of the actual worker object.</param>
|
||||
''' <param name="Assembly">The name of the assembly containing the actual worker class.</param>
|
||||
Public Sub New(ByVal Type As String, ByVal [Assembly] As String)
|
||||
mAssembly = [Assembly]
|
||||
mType = Type
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' The class name of the worker object.
|
||||
''' </summary>
|
||||
Public Property Type() As String
|
||||
Get
|
||||
Return mType
|
||||
End Get
|
||||
Set(ByVal Value As String)
|
||||
mType = Value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' The name of the assembly containing the actual worker class.
|
||||
''' </summary>
|
||||
Public Property [Assembly]() As String
|
||||
Get
|
||||
Return mAssembly
|
||||
End Get
|
||||
Set(ByVal Value As String)
|
||||
mAssembly = Value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' Executes the batch job on the server.
|
||||
''' </summary>
|
||||
''' <remarks>
|
||||
''' This method runs on the server - it is called
|
||||
''' by <see cref="T:CSLA.BatchQueue.Server.BatchEntry" />,
|
||||
''' which is called by
|
||||
''' <see cref="T:CSLA.BatchQueue.Server.BatchQueueService" />.
|
||||
''' </remarks>
|
||||
''' <param name="State"></param>
|
||||
Public Sub Execute(ByVal State As Object) _
|
||||
Implements IBatchEntry.Execute
|
||||
|
||||
' create an instance of the specified object
|
||||
Dim job As IBatchEntry
|
||||
job = CType(AppDomain.CurrentDomain.CreateInstanceAndUnwrap(mAssembly, mType), IBatchEntry)
|
||||
|
||||
' execute the job
|
||||
job.Execute(State)
|
||||
|
||||
End Sub
|
||||
|
||||
#Region " System.Object overrides "
|
||||
|
||||
Public Overrides Function ToString() As String
|
||||
|
||||
Return "BatchJobRequest: " & mType & "," & mAssembly
|
||||
|
||||
End Function
|
||||
|
||||
#End Region
|
||||
|
||||
End Class
|
||||
257
source/csla10/CSLA.BatchQueue/BatchQueue.vb
Normal file
257
source/csla10/CSLA.BatchQueue/BatchQueue.vb
Normal file
@@ -0,0 +1,257 @@
|
||||
Imports System.Runtime.Remoting.Channels
|
||||
Imports System.Runtime.Remoting.Channels.Tcp
|
||||
Imports System.Configuration
|
||||
|
||||
''' <summary>
|
||||
''' Provides easy access to the batch queue functionality.
|
||||
''' </summary>
|
||||
''' <remarks>
|
||||
''' Client code should create an instance of this class to
|
||||
''' interact with a batch queue. A BatchQueue object can
|
||||
''' be used to interact with either the default batch queue
|
||||
''' server or with a specific batch queue server.
|
||||
''' </remarks>
|
||||
Public Class BatchQueue
|
||||
Private mQueueURL As String
|
||||
Private mServer As Server.BatchQueue
|
||||
|
||||
#Region " Constructors and Initialization "
|
||||
|
||||
''' <summary>
|
||||
''' Creates an instance of the object that allows interaction
|
||||
''' with the default batch queue server as specified in the
|
||||
''' application configuration file.
|
||||
''' </summary>
|
||||
Public Sub New()
|
||||
|
||||
mQueueURL = ConfigurationSettings.AppSettings("DefaultBatchQueueServer")
|
||||
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Creates an instance of the object that allows interaction
|
||||
''' with a specific batch queue server as specified by
|
||||
''' the URL passed as a parameter.
|
||||
''' </summary>
|
||||
''' <param name="QueueServerURL">A URL referencing the batch queue server.</param>
|
||||
Public Sub New(ByVal QueueServerURL As String)
|
||||
|
||||
mQueueURL = QueueServerURL
|
||||
|
||||
End Sub
|
||||
|
||||
Private Function QueueServer() As Server.BatchQueue
|
||||
|
||||
If mServer Is Nothing Then
|
||||
mServer = _
|
||||
CType(Activator.GetObject(GetType(Server.BatchQueue), _
|
||||
mQueueURL), _
|
||||
Server.BatchQueue)
|
||||
|
||||
End If
|
||||
|
||||
Return mServer
|
||||
|
||||
End Function
|
||||
|
||||
#End Region
|
||||
|
||||
#Region " Submitting jobs "
|
||||
|
||||
''' <summary>
|
||||
''' Submits an entry to the batch queue.
|
||||
''' </summary>
|
||||
''' <param name="Entry">A reference to your worker object.</param>
|
||||
Public Sub Submit(ByVal Entry As IBatchEntry)
|
||||
|
||||
QueueServer.Submit(New Server.BatchEntry(Entry))
|
||||
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Submits an entry to the batch queue with extra state data.
|
||||
''' </summary>
|
||||
''' <param name="Entry">A reference to your worker object.</param>
|
||||
''' <param name="State">A reference to a serializable object containing state data.</param>
|
||||
Public Sub Submit(ByVal Entry As IBatchEntry, ByVal State As Object)
|
||||
|
||||
QueueServer.Submit(New Server.BatchEntry(Entry, State))
|
||||
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Submits an entry to the batch queue with a specific priority.
|
||||
''' </summary>
|
||||
''' <param name="Entry">A reference to your worker object.</param>
|
||||
''' <param name="Priority">The priority of the entry.</param>
|
||||
Public Sub Submit(ByVal Entry As IBatchEntry, _
|
||||
ByVal Priority As Messaging.MessagePriority)
|
||||
|
||||
Dim job As Server.BatchEntry = New Server.BatchEntry(Entry)
|
||||
job.Info.Priority = Priority
|
||||
QueueServer.Submit(job)
|
||||
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Submits an entry to the batch queue with extra state data and
|
||||
''' a specific priority.
|
||||
''' </summary>
|
||||
''' <param name="Entry">A reference to your worker object.</param>
|
||||
''' <param name="State">A reference to a serializable object containing state data.</param>
|
||||
''' <param name="Priority">The priority of the entry.</param>
|
||||
Public Sub Submit(ByVal Entry As IBatchEntry, _
|
||||
ByVal State As Object, _
|
||||
ByVal Priority As Messaging.MessagePriority)
|
||||
|
||||
Dim job As Server.BatchEntry = New Server.BatchEntry(Entry, State)
|
||||
job.Info.Priority = Priority
|
||||
QueueServer.Submit(job)
|
||||
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Submits an entry to the batch queue to be held until a specific date/time.
|
||||
''' </summary>
|
||||
''' <param name="Entry">A reference to your worker object.</param>
|
||||
''' <param name="HoldUntil">The date/time until which the entry should be held.</param>
|
||||
Public Sub Submit(ByVal Entry As IBatchEntry, ByVal HoldUntil As Date)
|
||||
|
||||
Dim job As Server.BatchEntry = New Server.BatchEntry(Entry)
|
||||
job.Info.HoldUntil = HoldUntil
|
||||
QueueServer.Submit(job)
|
||||
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Submits an entry to the batch queue with extra state data
|
||||
''' and to be held until a specific date/time.
|
||||
''' </summary>
|
||||
''' <param name="Entry">A reference to your worker object.</param>
|
||||
''' <param name="State">A reference to a serializable object containing state data.</param>
|
||||
''' <param name="HoldUntil">The date/time until which the entry should be held.</param>
|
||||
Public Sub Submit(ByVal Entry As IBatchEntry, _
|
||||
ByVal State As Object, _
|
||||
ByVal HoldUntil As Date)
|
||||
|
||||
Dim job As Server.BatchEntry = New Server.BatchEntry(Entry, State)
|
||||
job.Info.HoldUntil = HoldUntil
|
||||
QueueServer.Submit(job)
|
||||
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Submits an entry to the batch queue to be held until
|
||||
''' a specific date/time and at a specific priority.
|
||||
''' </summary>
|
||||
''' <param name="Entry">A reference to your worker object.</param>
|
||||
''' <param name="HoldUntil">The date/time until which the entry should be held.</param>
|
||||
''' <param name="Priority">The priority of the entry.</param>
|
||||
Public Sub Submit(ByVal Entry As IBatchEntry, _
|
||||
ByVal HoldUntil As Date, ByVal Priority As Messaging.MessagePriority)
|
||||
|
||||
Dim job As Server.BatchEntry = New Server.BatchEntry(Entry)
|
||||
job.Info.HoldUntil = HoldUntil
|
||||
job.Info.Priority = Priority
|
||||
QueueServer.Submit(job)
|
||||
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Submits an entry to the batch queue specifying all details.
|
||||
''' </summary>
|
||||
''' <param name="Entry">A reference to your worker object.</param>
|
||||
''' <param name="State">A reference to a serializable object containing state data.</param>
|
||||
''' <param name="HoldUntil">The date/time until which the entry should be held.</param>
|
||||
''' <param name="Priority">The priority of the entry.</param>
|
||||
Public Sub Submit(ByVal Entry As IBatchEntry, _
|
||||
ByVal State As Object, _
|
||||
ByVal HoldUntil As Date, _
|
||||
ByVal Priority As Messaging.MessagePriority)
|
||||
|
||||
Dim job As Server.BatchEntry = New Server.BatchEntry(Entry, State)
|
||||
job.Info.HoldUntil = HoldUntil
|
||||
job.Info.Priority = Priority
|
||||
QueueServer.Submit(job)
|
||||
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
|
||||
#Region " Public methods "
|
||||
|
||||
''' <summary>
|
||||
''' Removes a holding or pending entry from the
|
||||
''' batch queue.
|
||||
''' </summary>
|
||||
''' <param name="Entry">A reference to the entry to be removed.</param>
|
||||
Public Sub Remove(ByVal Entry As BatchEntryInfo)
|
||||
|
||||
QueueServer.Remove(Entry)
|
||||
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Returns the URL which identifies the batch
|
||||
''' queue server to which this object is attached.
|
||||
''' </summary>
|
||||
Public ReadOnly Property BatchQueueURL() As String
|
||||
Get
|
||||
Return mQueueURL
|
||||
End Get
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' Returns a collection of the batch entries currently
|
||||
''' in the batch queue.
|
||||
''' </summary>
|
||||
Public ReadOnly Property Entries() As BatchEntries
|
||||
Get
|
||||
Return QueueServer.GetEntries(GetPrincipal)
|
||||
End Get
|
||||
End Property
|
||||
|
||||
#End Region
|
||||
|
||||
#Region " System.Object overrides "
|
||||
|
||||
Public Overrides Function ToString() As String
|
||||
|
||||
Return mQueueURL
|
||||
|
||||
End Function
|
||||
|
||||
Public Overloads Function Equals(ByVal Queue As BatchQueue) As Boolean
|
||||
|
||||
Return mQueueURL = Queue.BatchQueueURL
|
||||
|
||||
End Function
|
||||
|
||||
Public Overrides Function GetHashCode() As Integer
|
||||
|
||||
Return mQueueURL.GetHashCode
|
||||
|
||||
End Function
|
||||
|
||||
#End Region
|
||||
|
||||
#Region " Security "
|
||||
|
||||
Private Function AUTHENTICATION() As String
|
||||
Return ConfigurationSettings.AppSettings("Authentication")
|
||||
End Function
|
||||
|
||||
Private Function GetPrincipal() As System.Security.Principal.IPrincipal
|
||||
If AUTHENTICATION() = "Windows" Then
|
||||
' Windows integrated security
|
||||
Return Nothing
|
||||
|
||||
Else
|
||||
' we assume using the CSLA framework security
|
||||
Return System.Threading.Thread.CurrentPrincipal
|
||||
End If
|
||||
End Function
|
||||
|
||||
#End Region
|
||||
|
||||
End Class
|
||||
103
source/csla10/CSLA.BatchQueue/BatchQueueServer.vb
Normal file
103
source/csla10/CSLA.BatchQueue/BatchQueueServer.vb
Normal file
@@ -0,0 +1,103 @@
|
||||
Imports System.Security.Principal
|
||||
Imports System.Configuration
|
||||
Imports CSLA.Security
|
||||
|
||||
''' <summary>
|
||||
'''
|
||||
''' </summary>
|
||||
Namespace Server
|
||||
|
||||
''' <summary>
|
||||
''' This is the entry point for all queue requests from
|
||||
''' the client via Remoting.
|
||||
''' </summary>
|
||||
Public Class BatchQueue
|
||||
Inherits MarshalByRefObject
|
||||
|
||||
#Region " Public methods "
|
||||
|
||||
''' <summary>
|
||||
''' Submits a batch entry to the queue.
|
||||
''' </summary>
|
||||
''' <param name="Entry">A reference to the batch entry.</param>
|
||||
Public Sub Submit(ByVal Entry As BatchEntry)
|
||||
|
||||
BatchQueueService.Enqueue(Entry)
|
||||
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Removes a holding or pending entry from the queue.
|
||||
''' </summary>
|
||||
''' <param name="Entry">A reference to the info object for the batch entry.</param>
|
||||
Public Sub Remove(ByVal Entry As BatchEntryInfo)
|
||||
|
||||
BatchQueueService.Dequeue(Entry)
|
||||
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Gets a list of the entries currently in the
|
||||
''' batch queue.
|
||||
''' </summary>
|
||||
''' <param name="Principal">The requesting user's security credentials.</param>
|
||||
Public Function GetEntries(ByVal Principal As IPrincipal) As BatchEntries
|
||||
|
||||
SetPrincipal(Principal)
|
||||
|
||||
Dim entries As New BatchEntries()
|
||||
BatchQueueService.LoadEntries(entries)
|
||||
|
||||
Return entries
|
||||
|
||||
End Function
|
||||
|
||||
#End Region
|
||||
|
||||
#Region " Security "
|
||||
|
||||
Private Function AUTHENTICATION() As String
|
||||
|
||||
Return ConfigurationSettings.AppSettings("Authentication")
|
||||
|
||||
End Function
|
||||
|
||||
Private Sub SetPrincipal(ByVal Principal As Object)
|
||||
If AUTHENTICATION() = "Windows" Then
|
||||
' when using integrated security, Principal must be Nothing
|
||||
' and we need to set our policy to use the Windows principal
|
||||
If Principal Is Nothing Then
|
||||
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal)
|
||||
Exit Sub
|
||||
|
||||
Else
|
||||
Throw New System.Security.SecurityException("No principal object should be passed to DataPortal when using Windows integrated security")
|
||||
End If
|
||||
End If
|
||||
|
||||
' we expect Principal to be of type BusinessPrincipal, but
|
||||
' we can't enforce that since it causes a circular reference
|
||||
' with the business library so instead we must use type Object
|
||||
' for the parameter, so here we do a check on the type of the
|
||||
' parameter
|
||||
If Principal.ToString = "CSLA.Security.BusinessPrincipal" Then
|
||||
' see if our current principal is
|
||||
' different from the caller's principal
|
||||
If Not ReferenceEquals(Principal, System.Threading.Thread.CurrentPrincipal) Then
|
||||
' the caller had a different principal, so change ours to
|
||||
' match the caller's so all our objects use the caller's
|
||||
' security
|
||||
System.Threading.Thread.CurrentPrincipal = CType(Principal, IPrincipal)
|
||||
End If
|
||||
|
||||
Else
|
||||
Throw New System.Security.SecurityException("Principal must be of type BusinessPrincipal, not " & Principal.ToString)
|
||||
End If
|
||||
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
|
||||
End Class
|
||||
|
||||
End Namespace
|
||||
337
source/csla10/CSLA.BatchQueue/BatchQueueService.vb
Normal file
337
source/csla10/CSLA.BatchQueue/BatchQueueService.vb
Normal file
@@ -0,0 +1,337 @@
|
||||
Imports System.Configuration
|
||||
Imports System.Messaging
|
||||
Imports System.Runtime.Remoting
|
||||
Imports System.Runtime.Remoting.Channels
|
||||
Imports System.Runtime.Remoting.Channels.Tcp
|
||||
Imports System.IO
|
||||
Imports System.Runtime.Serialization.Formatters.Binary
|
||||
|
||||
''' <summary>
|
||||
'''
|
||||
''' </summary>
|
||||
Namespace Server
|
||||
|
||||
''' <summary>
|
||||
''' Implements the batch queue service.
|
||||
''' </summary>
|
||||
''' <remarks>
|
||||
''' This class implements the server-side batch queue functionality.
|
||||
''' It must be hosted within some process, typically a Windows Service.
|
||||
''' It may also be hosted within a console application, which is
|
||||
''' useful for testing and debugging.
|
||||
''' </remarks>
|
||||
Public Class BatchQueueService
|
||||
|
||||
Private Shared mChannel As TcpServerChannel
|
||||
Private Shared mQueue As MessageQueue
|
||||
Private Shared mMonitor As Threading.Thread
|
||||
Private Shared WithEvents mTimer As New System.Timers.Timer
|
||||
Private Shared mRunning As Boolean
|
||||
Private Shared mActiveEntries As Hashtable = Hashtable.Synchronized(New Hashtable)
|
||||
|
||||
Private Shared mSync As New Threading.AutoResetEvent(False)
|
||||
Private Shared mWaitToEnd As New Threading.ManualResetEvent(False)
|
||||
|
||||
''' <summary>
|
||||
''' Returns the name of the batch queue server.
|
||||
''' </summary>
|
||||
Public Shared ReadOnly Property Name() As String
|
||||
Get
|
||||
Return LISTENER_NAME()
|
||||
End Get
|
||||
End Property
|
||||
|
||||
#Region " Start/Stop "
|
||||
|
||||
''' <summary>
|
||||
''' Starts the batch queue.
|
||||
''' </summary>
|
||||
''' <remarks>
|
||||
''' Call this as your Windows Service starts up to
|
||||
''' start the batch queue itself. This will cause
|
||||
''' the queue to start listening for user requests
|
||||
''' via remoting and to the MSMQ for queued jobs.
|
||||
''' </remarks>
|
||||
Public Shared Sub Start()
|
||||
|
||||
mTimer.AutoReset = False
|
||||
|
||||
' open and/or create queue
|
||||
If MessageQueue.Exists(QUEUE_NAME) Then
|
||||
mQueue = New MessageQueue(QUEUE_NAME)
|
||||
|
||||
Else
|
||||
mQueue = MessageQueue.Create(QUEUE_NAME)
|
||||
End If
|
||||
mQueue.MessageReadPropertyFilter.Extension = True
|
||||
|
||||
' start reading from queue
|
||||
mRunning = True
|
||||
mMonitor = New Threading.Thread(AddressOf MonitorQueue)
|
||||
mMonitor.Name = "MonitorQueue"
|
||||
mMonitor.Start()
|
||||
|
||||
' start remoting for Server.BatchQueue
|
||||
If mChannel Is Nothing Then
|
||||
' set application name (virtual root name)
|
||||
RemotingConfiguration.ApplicationName = LISTENER_NAME()
|
||||
|
||||
' set up channel
|
||||
Dim properties As New Hashtable()
|
||||
properties("name") = "TcpBinary"
|
||||
properties("priority") = "2"
|
||||
properties("port") = CStr(PORT())
|
||||
Dim svFormatter As New BinaryServerFormatterSinkProvider()
|
||||
|
||||
'TODO: uncomment the following line for .NET 1.1
|
||||
'svFormatter.TypeFilterLevel = Runtime.Serialization.Formatters.TypeFilterLevel.Full
|
||||
|
||||
mChannel = New TcpServerChannel(properties, svFormatter)
|
||||
Channels.ChannelServices.RegisterChannel(mChannel)
|
||||
|
||||
' register our class
|
||||
RemotingConfiguration.RegisterWellKnownServiceType( _
|
||||
GetType(Server.BatchQueue), _
|
||||
"BatchQueue.rem", _
|
||||
WellKnownObjectMode.SingleCall)
|
||||
|
||||
Else
|
||||
mChannel.StartListening(Nothing)
|
||||
End If
|
||||
|
||||
Dim sb As New Text.StringBuilder()
|
||||
|
||||
sb.Append("Batch queue processor started")
|
||||
sb.Append(vbCrLf)
|
||||
sb.AppendFormat("Name: {0}", Name)
|
||||
sb.Append(vbCrLf)
|
||||
sb.AppendFormat("Port: {0}", PORT)
|
||||
sb.Append(vbCrLf)
|
||||
sb.AppendFormat("Queue: {0}", QUEUE_NAME)
|
||||
sb.Append(vbCrLf)
|
||||
sb.AppendFormat("Max jobs: {0}", MAX_ENTRIES)
|
||||
sb.Append(vbCrLf)
|
||||
System.Diagnostics.EventLog.WriteEntry( _
|
||||
Name, sb.ToString, EventLogEntryType.Information)
|
||||
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Stops the batch queue.
|
||||
''' </summary>
|
||||
''' <remarks>
|
||||
''' <para>
|
||||
''' Call this as your Windows Service is stopping. It
|
||||
''' stops the batch queue, causing it to stop listening
|
||||
''' for user requests via remoting and to stop looking for
|
||||
''' jobs in the MSMQ queue.
|
||||
''' </para><para>
|
||||
''' NOTE that this method will not return until any
|
||||
''' currently active (executing) batch jobs have completed.
|
||||
''' </para>
|
||||
''' </remarks>
|
||||
Public Shared Sub [Stop]()
|
||||
|
||||
' stop remoting for Server.BatchQueue
|
||||
mChannel.StopListening(Nothing)
|
||||
|
||||
' signal to stop working
|
||||
mRunning = False
|
||||
mSync.Set()
|
||||
mMonitor.Join()
|
||||
' close the queue
|
||||
mQueue.Close()
|
||||
|
||||
If mActiveEntries.Count > 0 Then
|
||||
' wait for work to end
|
||||
mWaitToEnd.WaitOne()
|
||||
End If
|
||||
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
|
||||
#Region " Process messages "
|
||||
|
||||
' this will be running on a background thread
|
||||
Private Shared Sub MonitorQueue()
|
||||
|
||||
While mRunning
|
||||
ScanQueue()
|
||||
mSync.WaitOne()
|
||||
End While
|
||||
|
||||
End Sub
|
||||
|
||||
' this runs on a threadpool thread
|
||||
Private Shared Sub mTimer_Elapsed(ByVal sender As Object, _
|
||||
ByVal e As System.Timers.ElapsedEventArgs) Handles mTimer.Elapsed
|
||||
|
||||
mTimer.Stop()
|
||||
mSync.Set()
|
||||
|
||||
End Sub
|
||||
|
||||
' this is called by MonitorQueue
|
||||
Private Shared Sub ScanQueue()
|
||||
|
||||
Dim msg As Message
|
||||
Dim holdUntil As Date
|
||||
Dim nextWake As Date = Date.MaxValue
|
||||
|
||||
Dim en As MessageEnumerator = mQueue.GetMessageEnumerator
|
||||
While en.MoveNext()
|
||||
msg = en.Current
|
||||
holdUntil = CDate(Text.Encoding.ASCII.GetString(msg.Extension))
|
||||
If holdUntil <= Now Then
|
||||
If mActiveEntries.Count < MAX_ENTRIES() Then
|
||||
ProcessEntry(mQueue.ReceiveById(msg.Id))
|
||||
|
||||
Else
|
||||
' the queue is busy, go to sleep
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
ElseIf holdUntil < nextWake Then
|
||||
' find the minimum holduntil value
|
||||
nextWake = holdUntil
|
||||
End If
|
||||
End While
|
||||
|
||||
If nextWake < Date.MaxValue AndAlso nextWake > Now Then
|
||||
' we have at least one entry holding, so set the
|
||||
' timer to wake us when it should be run
|
||||
mTimer.Interval = nextWake.Subtract(Now).TotalMilliseconds
|
||||
mTimer.Start()
|
||||
End If
|
||||
|
||||
End Sub
|
||||
|
||||
Private Shared Sub ProcessEntry(ByVal msg As Message)
|
||||
|
||||
' get entry from queue
|
||||
Dim entry As BatchEntry
|
||||
Dim formatter As New BinaryFormatter()
|
||||
entry = CType(formatter.Deserialize(msg.BodyStream), BatchEntry)
|
||||
|
||||
' make active
|
||||
entry.Info.SetStatus(BatchEntryStatus.Active)
|
||||
mActiveEntries.Add(entry.Info.ID, entry.Info)
|
||||
|
||||
' start processing entry on background thread
|
||||
Threading.ThreadPool.QueueUserWorkItem(AddressOf entry.Execute)
|
||||
|
||||
End Sub
|
||||
|
||||
' called by BatchEntry when it is done processing so
|
||||
' we know that it is complete and we can start another
|
||||
' job if needed
|
||||
Friend Shared Sub Deactivate(ByVal entry As BatchEntry)
|
||||
|
||||
mActiveEntries.Remove(entry.Info.ID)
|
||||
mSync.Set()
|
||||
If Not mRunning AndAlso mActiveEntries.Count = 0 Then
|
||||
' indicate that there are no active workers
|
||||
mWaitToEnd.Set()
|
||||
End If
|
||||
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
|
||||
#Region " Enqueue/Dequeue/LoadEntries "
|
||||
|
||||
Friend Shared Sub Enqueue(ByVal Entry As BatchEntry)
|
||||
|
||||
Dim msg As New Message()
|
||||
Dim f As New BinaryFormatter()
|
||||
|
||||
With msg
|
||||
.Label = Entry.ToString
|
||||
.Priority = Entry.Info.Priority
|
||||
.Extension = Text.Encoding.ASCII.GetBytes(CStr(Entry.Info.HoldUntil))
|
||||
Entry.Info.SetMessageID(.Id)
|
||||
f.Serialize(.BodyStream, Entry)
|
||||
End With
|
||||
|
||||
mQueue.Send(msg)
|
||||
|
||||
mSync.Set()
|
||||
|
||||
End Sub
|
||||
|
||||
Friend Shared Sub Dequeue(ByVal Entry As BatchEntryInfo)
|
||||
|
||||
Dim label As String
|
||||
Dim msg As Message
|
||||
Dim msgID As String
|
||||
|
||||
label = Entry.ToString
|
||||
Dim en As MessageEnumerator = mQueue.GetMessageEnumerator
|
||||
mQueue.MessageReadPropertyFilter.Label = True
|
||||
|
||||
While en.MoveNext()
|
||||
If en.Current.Label = label Then
|
||||
' we found a match
|
||||
msgID = en.Current.Id
|
||||
Exit While
|
||||
End If
|
||||
End While
|
||||
|
||||
If Len(msgID) > 0 Then
|
||||
mQueue.ReceiveById(msgID)
|
||||
End If
|
||||
|
||||
End Sub
|
||||
|
||||
Friend Shared Sub LoadEntries(ByVal List As BatchEntries)
|
||||
|
||||
' load our list of BatchEntry objects
|
||||
Dim msgs() As Message
|
||||
Dim msg As Message
|
||||
Dim formatter As New BinaryFormatter()
|
||||
Dim de As DictionaryEntry
|
||||
Dim entry As Server.BatchEntry
|
||||
|
||||
' get all active entries
|
||||
SyncLock mActiveEntries.SyncRoot
|
||||
For Each de In Server.BatchQueueService.mActiveEntries
|
||||
List.Add(CType(de.Value, BatchEntryInfo))
|
||||
Next
|
||||
End SyncLock
|
||||
|
||||
' get all queued entries
|
||||
msgs = mQueue.GetAllMessages
|
||||
For Each msg In msgs
|
||||
entry = CType(formatter.Deserialize(msg.BodyStream), Server.BatchEntry)
|
||||
entry.Info.SetMessageID(msg.Id)
|
||||
List.Add(entry.Info)
|
||||
Next
|
||||
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
|
||||
#Region " Utility functions "
|
||||
|
||||
Private Shared Function QUEUE_NAME() As String
|
||||
Return ".\private$\" & ConfigurationSettings.AppSettings("QueueName")
|
||||
End Function
|
||||
|
||||
Private Shared Function LISTENER_NAME() As String
|
||||
Return ConfigurationSettings.AppSettings("ListenerName")
|
||||
End Function
|
||||
|
||||
Private Shared Function PORT() As Integer
|
||||
Return CInt(ConfigurationSettings.AppSettings("ListenerPort"))
|
||||
End Function
|
||||
|
||||
Private Shared Function MAX_ENTRIES() As Integer
|
||||
Return CInt(ConfigurationSettings.AppSettings("MaxActiveEntries"))
|
||||
End Function
|
||||
|
||||
#End Region
|
||||
|
||||
End Class
|
||||
|
||||
End Namespace
|
||||
137
source/csla10/CSLA.BatchQueue/CSLA.BatchQueue.vbproj
Normal file
137
source/csla10/CSLA.BatchQueue/CSLA.BatchQueue.vbproj
Normal file
@@ -0,0 +1,137 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ProjectType>Local</ProjectType>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{F8E2709C-E0DE-4253-9A1A-59F4F59B0EBD}</ProjectGuid>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ApplicationIcon>
|
||||
</ApplicationIcon>
|
||||
<AssemblyKeyContainerName>
|
||||
</AssemblyKeyContainerName>
|
||||
<AssemblyName>CSLA.BatchQueue</AssemblyName>
|
||||
<AssemblyOriginatorKeyFile>
|
||||
</AssemblyOriginatorKeyFile>
|
||||
<AssemblyOriginatorKeyMode>None</AssemblyOriginatorKeyMode>
|
||||
<DefaultClientScript>JScript</DefaultClientScript>
|
||||
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
|
||||
<DefaultTargetSchema>IE50</DefaultTargetSchema>
|
||||
<DelaySign>false</DelaySign>
|
||||
<OutputType>Library</OutputType>
|
||||
<OptionCompare>Binary</OptionCompare>
|
||||
<OptionExplicit>On</OptionExplicit>
|
||||
<OptionStrict>Off</OptionStrict>
|
||||
<RootNamespace>CSLA.BatchQueue</RootNamespace>
|
||||
<StartupObject>
|
||||
</StartupObject>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<MyType>Windows</MyType>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<DocumentationFile>CSLA.BatchQueue.xml</DocumentationFile>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<ConfigurationOverrideFile>
|
||||
</ConfigurationOverrideFile>
|
||||
<DefineConstants>
|
||||
</DefineConstants>
|
||||
<DefineDebug>true</DefineDebug>
|
||||
<DefineTrace>true</DefineTrace>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<Optimize>false</Optimize>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<RemoveIntegerChecks>false</RemoveIntegerChecks>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<WarningLevel>1</WarningLevel>
|
||||
<NoWarn>42016,42017,42018,42019,42032</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<DocumentationFile>CSLA.BatchQueue.xml</DocumentationFile>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<ConfigurationOverrideFile>
|
||||
</ConfigurationOverrideFile>
|
||||
<DefineConstants>
|
||||
</DefineConstants>
|
||||
<DefineDebug>false</DefineDebug>
|
||||
<DefineTrace>true</DefineTrace>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<Optimize>true</Optimize>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<RemoveIntegerChecks>false</RemoveIntegerChecks>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<WarningLevel>1</WarningLevel>
|
||||
<NoWarn>42016,42017,42018,42019,42032</NoWarn>
|
||||
<DebugType>none</DebugType>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System">
|
||||
<Name>System</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Data">
|
||||
<Name>System.Data</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Messaging">
|
||||
<Name>System.Messaging</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Remoting">
|
||||
<Name>System.Runtime.Remoting</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml">
|
||||
<Name>System.XML</Name>
|
||||
</Reference>
|
||||
<ProjectReference Include="..\CSLA\CSLA.vbproj">
|
||||
<Name>CSLA</Name>
|
||||
<Project>{1B9A38BB-461A-47A4-AD72-099C694138A0}</Project>
|
||||
<Package>{F184B08F-C81C-45F6-A57F-5ABD9991F28F}</Package>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Import Include="Microsoft.VisualBasic" />
|
||||
<Import Include="System" />
|
||||
<Import Include="System.Collections" />
|
||||
<Import Include="System.Data" />
|
||||
<Import Include="System.Diagnostics" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AssemblyInfo.vb">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="BatchEntries.vb">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="BatchEntry.vb">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="BatchEntryInfo.vb">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="BatchJobRequest.vb">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="BatchQueue.vb">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="BatchQueueServer.vb">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="BatchQueueService.vb">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="IBatchEntry.vb">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.VisualBasic.targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
58
source/csla10/CSLA.BatchQueue/CSLA.BatchQueue.vbproj.user
Normal file
58
source/csla10/CSLA.BatchQueue/CSLA.BatchQueue.vbproj.user
Normal file
@@ -0,0 +1,58 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<LastOpenVersion>7.10.3077</LastOpenVersion>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ReferencePath>
|
||||
</ReferencePath>
|
||||
<CopyProjectDestinationFolder>
|
||||
</CopyProjectDestinationFolder>
|
||||
<CopyProjectUncPath>
|
||||
</CopyProjectUncPath>
|
||||
<CopyProjectOption>0</CopyProjectOption>
|
||||
<ProjectView>ProjectFiles</ProjectView>
|
||||
<ProjectTrust>0</ProjectTrust>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<EnableASPDebugging>false</EnableASPDebugging>
|
||||
<EnableASPXDebugging>false</EnableASPXDebugging>
|
||||
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||
<EnableSQLServerDebugging>false</EnableSQLServerDebugging>
|
||||
<RemoteDebugEnabled>false</RemoteDebugEnabled>
|
||||
<RemoteDebugMachine>
|
||||
</RemoteDebugMachine>
|
||||
<StartAction>Project</StartAction>
|
||||
<StartArguments>
|
||||
</StartArguments>
|
||||
<StartPage>
|
||||
</StartPage>
|
||||
<StartProgram>
|
||||
</StartProgram>
|
||||
<StartURL>
|
||||
</StartURL>
|
||||
<StartWorkingDirectory>
|
||||
</StartWorkingDirectory>
|
||||
<StartWithIE>false</StartWithIE>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<EnableASPDebugging>false</EnableASPDebugging>
|
||||
<EnableASPXDebugging>false</EnableASPXDebugging>
|
||||
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||
<EnableSQLServerDebugging>false</EnableSQLServerDebugging>
|
||||
<RemoteDebugEnabled>false</RemoteDebugEnabled>
|
||||
<RemoteDebugMachine>
|
||||
</RemoteDebugMachine>
|
||||
<StartAction>Project</StartAction>
|
||||
<StartArguments>
|
||||
</StartArguments>
|
||||
<StartPage>
|
||||
</StartPage>
|
||||
<StartProgram>
|
||||
</StartProgram>
|
||||
<StartURL>
|
||||
</StartURL>
|
||||
<StartWorkingDirectory>
|
||||
</StartWorkingDirectory>
|
||||
<StartWithIE>false</StartWithIE>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
18
source/csla10/CSLA.BatchQueue/IBatchEntry.vb
Normal file
18
source/csla10/CSLA.BatchQueue/IBatchEntry.vb
Normal file
@@ -0,0 +1,18 @@
|
||||
''' <summary>
|
||||
''' Defines the interface that must be implemented by
|
||||
''' all worker classes.
|
||||
''' </summary>
|
||||
''' <remarks>
|
||||
''' To create a worker that can be executed within the
|
||||
''' batch queue, implement this interface. The interface
|
||||
''' will be invoked by the batch queue processor on the
|
||||
''' server.
|
||||
''' </remarks>
|
||||
Public Interface IBatchEntry
|
||||
''' <summary>
|
||||
''' This method should contain your worker code that
|
||||
''' is to be run in the batch queue.
|
||||
''' </summary>
|
||||
''' <param name="State">An optional object containing extra state data from the client.</param>
|
||||
Sub Execute(ByVal State As Object)
|
||||
End Interface
|
||||
@@ -0,0 +1 @@
|
||||
obj\Release\ResolveAssemblyReference.cache
|
||||
Binary file not shown.
Reference in New Issue
Block a user