Last active
August 29, 2015 14:05
-
-
Save rod-dot-codes/58436f72e58345c7fd14 to your computer and use it in GitHub Desktop.
Create's SQL Simulated Workers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
DECLARE @Process VARCHAR(1) = 'C' | |
--CREATE DATABASE SimulatedWorkers; | |
--GO | |
--DROP TABLE SimulatedWorkers.dbo.Jobs; | |
--GO | |
--CREATE TABLE SimulatedWorkers.dbo.Jobs ( | |
--JobId int PRIMARY KEY IDENTITY(1,1), JobCommand VARCHAR(max), JobStatus VARCHAR(1), LockedByWorker uniqueidentifier, JobOutput VARCHAR(max) | |
--) | |
--GO | |
DECLARE @cpu_count int = (SELECT cpu_count FROM sys.dm_os_sys_info) | |
PRINT 'CPU COUNT' | |
PRINT @cpu_count | |
DECLARE @subthreads int = (SELECT CEILING(1.5*@cpu_count)) | |
PRINT 'THREADS' | |
PRINT @subthreads | |
PRINT '----------------------------------------------' | |
PRINT 'CREATING OR DELETING WORKERS' | |
--Create the threads to handle the workload | |
IF @Process = 'C' | |
BEGIN | |
EXEC msdb.dbo.sp_add_job @job_name = 'Simulated Process Controller',@start_step_id =1 | |
--We now create the jobs that execute the outstanding workers | |
EXEC msdb.dbo.sp_add_jobstep | |
@job_name = 'Simulated Process Controller', | |
@step_name = N'Check and execute available job', | |
@subsystem = N'TSQL', | |
@database_name = N'SimulatedWorkers', | |
@command = N'EXEC dbo.JobController' | |
EXEC msdb.dbo.sp_add_jobserver @job_name = 'Simulated Process Controller', @server_name = N'(local)' | |
END | |
IF @Process = 'D' | |
BEGIN | |
EXEC msdb.dbo.sp_delete_job @job_name = 'Simulated Process Controller' | |
END | |
DECLARE @x int = 1 | |
WHILE (@x <= @subthreads) | |
BEGIN | |
PRINT @x | |
DECLARE @job_name VARCHAR(255) = 'Simulated Process'+CONVERT(VARCHAR,@x) | |
IF @Process = 'C' | |
BEGIN | |
--C for Create Workers | |
EXEC msdb.dbo.sp_add_job @job_name = @job_name,@start_step_id =1 | |
--We now create the jobs that execute the outstanding workers | |
EXEC msdb.dbo.sp_add_jobstep | |
@job_name = @job_name, | |
@step_name = N'Check and execute available job', | |
@subsystem = N'TSQL', | |
@database_name = N'SimulatedWorkers', | |
@command = N'EXEC dbo.ExecuteJob' | |
EXEC msdb.dbo.sp_add_jobserver @job_name = @job_name, @server_name = N'(local)' | |
END | |
IF @Process = 'D' | |
BEGIN | |
--D for Delete | |
EXEC msdb.dbo.sp_delete_job @job_name = @job_name | |
END | |
SET @x = @x + 1 | |
END |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
USE [SimulatedWorkers] | |
GO | |
/****** Object: StoredProcedure [dbo].[ExecuteJob] Script Date: 8/8/2014 12:04:56 PM ******/ | |
SET ANSI_NULLS ON | |
GO | |
SET QUOTED_IDENTIFIER ON | |
GO | |
-- ============================================= | |
-- Author: Rodney Hawkins | |
-- Create date: 2014 | |
-- Description: Simulates a process, allowing stored procedures to be parallized where they were previously not. | |
-- ============================================= | |
ALTER PROCEDURE [dbo].[ExecuteJob] | |
AS | |
BEGIN | |
-- SET NOCOUNT ON added to prevent extra result sets from | |
-- interfering with SELECT statements. | |
SET NOCOUNT ON; | |
start: | |
DECLARE @ThreadGuid uniqueidentifier | |
SET @ThreadGuid = NEWID() | |
--We first check for a job. | |
--Use NEWID() to ensure two Simulated Processes do not fight over the same Job. | |
DECLARE @job_id int = (SELECT top 1 JobId FROM dbo.Jobs where JobStatus = 'W' ORDER BY NEWID()) | |
IF @job_id is null | |
BEGIN | |
RAISERROR ('There are no jobs to process, so this job process is exiting.', -- Message text. | |
16, -- Severity. | |
1 -- State. | |
); | |
END | |
--Try and lock the Job_Id so that it is ours | |
UPDATE dbo.Jobs SET JobStatus = 'R',LockedByWorker=@ThreadGuid where JobId = @job_id and JobStatus = 'W' | |
--Ensure that the Job is actually locked by the worker or continue to the next step to be reallocated a task | |
DECLARE @allocated_job_thread uniqueidentifier = (SELECT LockedByWorker FROM dbo.Jobs where JobId = @job_id) | |
IF (@allocated_job_thread = @ThreadGuid) | |
BEGIN | |
DECLARE @attempts int = 0 | |
--This thread has been allocated the job, so we now execute it. | |
attempt: | |
PRINT 'A job has been allocated' | |
PRINT @job_id | |
DECLARE @sql_command NVARCHAR(max) = (SELECT JobCommand FROM dbo.Jobs where JobId = @job_id) | |
BEGIN TRY | |
EXEC sp_executesql @sql_command | |
UPDATE dbo.Jobs SET JobStatus = 'C' where JobId = @job_id | |
END TRY | |
BEGIN CATCH | |
PRINT ERROR_MESSAGE() | |
SET @attempts = @attempts + 1 | |
IF (@attempts > 5) | |
BEGIN | |
UPDATE dbo.Jobs SET JobStatus = 'F' where JobId = @job_id | |
END | |
ELSE | |
BEGIN | |
GOTO attempt --Yeah GOTO! | |
END | |
END CATCH | |
END | |
WAITFOR DELAY '00:00:01' | |
GOTO start | |
END |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
USE [SimulatedWorkers] | |
GO | |
/****** Object: StoredProcedure [dbo].[JobController] Script Date: 8/8/2014 12:05:07 PM ******/ | |
SET ANSI_NULLS ON | |
GO | |
SET QUOTED_IDENTIFIER ON | |
GO | |
-- ============================================= | |
-- Author: Rodney Hawkins | |
-- Create date: 25 July 2014 | |
-- Description: Check's if there are jobs available and if there are jobs available, | |
-- start's workers to execute them. | |
-- ============================================= | |
ALTER PROCEDURE [dbo].[JobController] | |
AS | |
BEGIN | |
-- SET NOCOUNT ON added to prevent extra result sets from | |
-- interfering with SELECT statements. | |
SET NOCOUNT ON; | |
DECLARE @cpu_count int = (SELECT cpu_count FROM sys.dm_os_sys_info) | |
DECLARE @threads int = (SELECT CEILING(1.5*@cpu_count)) | |
DECLARE @jobs_requiring_threads int = (SELECT COUNT(*) FROM dbo.Jobs where JobStatus = 'W') | |
IF (@jobs_requiring_threads = 0) | |
BEGIN | |
RAISERROR ('There are no jobs to process, so this controller job is exiting.', -- Message text. | |
16, -- Severity. | |
1 -- State. | |
); | |
END | |
IF (@jobs_requiring_threads > @threads) | |
SET @jobs_requiring_threads = @threads | |
DECLARE @x int = 1 | |
WHILE (@x <= @jobs_requiring_threads) | |
BEGIN | |
DECLARE @job_name VARCHAR(20) = 'Simulated Process'+CONVERT(VARCHAR,@x) | |
EXEC msdb.dbo.sp_start_job @job_name | |
SET @x = @x+1 | |
END | |
END |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment