Queue process

using BetterBusiness.AzureQueueStorage.MessageSerializer;
using Microsoft.Extensions.DependencyInjection;

namespace BetterBusiness.AzureQueueStorage.Infrastructure
{
public static class DependencyInjectionRegistry
{
public static IServiceCollection AddAzureQueueStorage(this IServiceCollection services, QueueConfig queueConfig)
{
services.AddSingleton(queueConfig);
services.AddSingleton<IMessageSerializer, JsonMessageSerializer>();
services.AddSingleton<ICloudQueueClientFactory, CloudQueueClientFactory>();
services.AddTransient<IQueueCommunicator, QueueCommunicator>();
return services;
}
}
}

using System;
using System.IO;
using System.IO.Compression;
using System.Text;

namespace BetterBusiness.AzureQueueStorage.Infrastructure
{
public static class StringExtension
{
///
/// Compresses the string.
///
/// The text.
///
public static string ToCompressed(this string text)
{
byte[] buffer = Encoding.UTF8.GetBytes(text);
var memoryStream = new MemoryStream();
using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Compress, true))
{
gZipStream.Write(buffer, 0, buffer.Length);
}

		memoryStream.Position = 0;

		var compressedData = new byte[memoryStream.Length];
		memoryStream.Read(compressedData, 0, compressedData.Length);

		var gZipBuffer = new byte[compressedData.Length + 4];
		Buffer.BlockCopy(compressedData, 0, gZipBuffer, 4, compressedData.Length);
		Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gZipBuffer, 0, 4);
		return Convert.ToBase64String(gZipBuffer);
	}

	/// <summary>
	/// Decompresses the string.
	/// </summary>
	/// <param name="compressedText">The compressed text.</param>
	/// <returns></returns>
	public static string ToDecompressed(this string compressedText)
	{
		byte[] gZipBuffer = Convert.FromBase64String(compressedText);
		using (var memoryStream = new MemoryStream())
		{
			int dataLength = BitConverter.ToInt32(gZipBuffer, 0);
			memoryStream.Write(gZipBuffer, 4, gZipBuffer.Length - 4);

			var buffer = new byte[dataLength];

			memoryStream.Position = 0;
			using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
			{
				gZipStream.Read(buffer, 0, buffer.Length);
			}

			return Encoding.UTF8.GetString(buffer);
		}
	}
}

}

using Newtonsoft.Json;

namespace BetterBusiness.AzureQueueStorage.Messages
{
public abstract class BaseQueueMessage
{
[JsonIgnore]
public string Route { get; set; }

	public BaseQueueMessage(string route)
	{
		Route = route;
	}
}

}

namespace BetterBusiness.AzureQueueStorage.Messages
{
public class SendEmailCommand : BaseQueueMessage
{
public string To { get; set; }
public string Subject { get; set; }
public string Body { get; set; }

	public SendEmailCommand()
		: base(QueueRoutes.EmailBox)
	{
	}
}

}

namespace BetterBusiness.AzureQueueStorage.MessageSerializer
{
public interface IMessageSerializer
{
T Deserialize(string message);
string Serialize(object obj);
}
}
using BetterBusiness.AzureQueueStorage.Infrastructure;
using Newtonsoft.Json;

namespace BetterBusiness.AzureQueueStorage.MessageSerializer
{
public class JsonMessageSerializer : IMessageSerializer
{
public T Deserialize(string message)
{
var obj = JsonConvert.DeserializeObject(message.ToDecompressed());
return obj;
}

	public string Serialize(object obj)
	{
		var message = JsonConvert.SerializeObject(obj);
		return message.ToCompressed();
	}
}

}

using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Queue;

namespace BetterBusiness.AzureQueueStorage
{
public interface ICloudQueueClientFactory
{
CloudQueueClient GetClient();
}

public class CloudQueueClientFactory : ICloudQueueClientFactory
{
	private readonly QueueConfig _queueConfig;
	private CloudQueueClient _cloudQueueClient;

	public CloudQueueClientFactory(QueueConfig queueConfig)
	{
		_queueConfig = queueConfig;
	}

	public CloudQueueClient GetClient()
	{
		if (_cloudQueueClient != null)
			return _cloudQueueClient;

		var storageAccount = CloudStorageAccount.Parse(_queueConfig.QueueConnectionString);
		_cloudQueueClient = storageAccount.CreateCloudQueueClient();
		return _cloudQueueClient;
	}
}

}

using BetterBusiness.AzureQueueStorage.Messages;
using BetterBusiness.AzureQueueStorage.MessageSerializer;
using Microsoft.WindowsAzure.Storage.Queue;
using System.Threading.Tasks;

namespace BetterBusiness.AzureQueueStorage
{
public interface IQueueCommunicator
{
T Read(string message);
Task SendAsync(T obj) where T : BaseQueueMessage;
}

public class QueueCommunicator : IQueueCommunicator
{
	private readonly IMessageSerializer _messageSerializer;
	private readonly ICloudQueueClientFactory _cloudQueueClientFactory;

	public QueueCommunicator(
		IMessageSerializer messageSerializer,
		ICloudQueueClientFactory cloudQueueClientFactory)
	{
		_messageSerializer = messageSerializer;
		_cloudQueueClientFactory = cloudQueueClientFactory;
	}

	public T Read<T>(string message)
	{
		return _messageSerializer.Deserialize<T>(message);
	}

	public async Task SendAsync<T>(T obj) where T : BaseQueueMessage
	{
		var queueReference = _cloudQueueClientFactory.GetClient().GetQueueReference(obj.Route);
		await queueReference.CreateIfNotExistsAsync();

		var serialize = _messageSerializer.Serialize(obj);
		var queueMessage = new CloudQueueMessage(serialize);
		await queueReference.AddMessageAsync(queueMessage);
	}
}

}
using System;

namespace BetterBusiness.AzureQueueStorage
{
public class QueueConfig
{
public string QueueConnectionString { get; set; }

	public QueueConfig(string queueConnectionString)
	{
		if (string.IsNullOrEmpty(queueConnectionString))
			throw new ArgumentException("QueueConfig.QueueConnectionString cannot be null or empty");
		QueueConnectionString = queueConnectionString;
	}
}

}

namespace BetterBusiness.AzureQueueStorage
{
public class QueueRoutes
{
public const string EmailBox = “email-box”;
}
}

将进程原子地添加到进程队列中是一个涉及并发控制的过程。为了保证操作的原子性(即要么完全执行,要么根本不执行),通常会采用一些同步机制来防止多个线程或进程同时修改队列导致的数据不一致。 以下是实现这一过程的一些关键点: ### 原子性的意义 当我们将一个新进程加入队列时,需要确保这个动作不会受到其他线程或进程干扰。如果缺乏适当的保护措施,在高并发环境下可能会引发竞争条件、数据损坏或其他不可预测的行为。 ### 实现方式 可以利用锁(Locks)、信号量(Semaphores) 或者硬件提供的特殊指令集如 compare-and-swap (CAS) 来达成目标: #### 使用互斥锁(Mutex) 这是最简单直接的方式之一。通过获取一把全局互斥锁来串行化对共享资源(此处指代队列结构) 的访问。 ```c++ std::mutex mtx; void atomic_add_to_queue(std::queue<int>& q, int process_id){ std::lock_guard<std::mutex> lock(mtx); // 自动上锁及解锁 q.push(process_id); } ``` #### CAS 操作 对于性能敏感场景下减少上下文切换开销的需求,则可以选择基于无锁算法的设计思路,例如借助于 C++ 中 `atomic` 类型配合特定内存屏障完成类似任务。 ### 示例代码片段(Python版): 假设我们有一个简单的 FIFO 队列用于存储待处理的任务 ID 列表. ```python import threading class AtomicQueue: def __init__(self): self.queue = [] self.lock = threading.Lock() def enqueue(self, item): with self.lock: # 加锁区域开始 self.queue.append(item) # 执行入队操作 print(f"Process {item} added.") ``` 上述例子展示了如何创建一个支持安全入队功能的小型库函数集合;实际应用当中可根据具体需求选择合适的技术方案加以实现.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值