@@ -0,0 +1,23 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using System.Windows.Forms; | |||||
namespace WInFormApp | |||||
{ | |||||
static class Program | |||||
{ | |||||
/// <summary> | |||||
/// The main entry point for the application. | |||||
/// </summary> | |||||
[STAThread] | |||||
static void Main() | |||||
{ | |||||
Application.SetHighDpiMode(HighDpiMode.SystemAware); | |||||
Application.EnableVisualStyles(); | |||||
Application.SetCompatibleTextRenderingDefault(false); | |||||
Application.Run(new StartForm()); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,90 @@ | |||||
| |||||
namespace WInFormApp | |||||
{ | |||||
partial class StartForm | |||||
{ | |||||
/// <summary> | |||||
/// Required designer variable. | |||||
/// </summary> | |||||
private System.ComponentModel.IContainer components = null; | |||||
/// <summary> | |||||
/// Clean up any resources being used. | |||||
/// </summary> | |||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> | |||||
protected override void Dispose(bool disposing) | |||||
{ | |||||
if (disposing && (components != null)) | |||||
{ | |||||
components.Dispose(); | |||||
} | |||||
base.Dispose(disposing); | |||||
} | |||||
#region Windows Form Designer generated code | |||||
/// <summary> | |||||
/// Required method for Designer support - do not modify | |||||
/// the contents of this method with the code editor. | |||||
/// </summary> | |||||
private void InitializeComponent() | |||||
{ | |||||
this.btnGen = new System.Windows.Forms.Button(); | |||||
this.txtIdList = new System.Windows.Forms.TextBox(); | |||||
this.button1 = new System.Windows.Forms.Button(); | |||||
this.SuspendLayout(); | |||||
// | |||||
// btnGen | |||||
// | |||||
this.btnGen.Location = new System.Drawing.Point(12, 385); | |||||
this.btnGen.Name = "btnGen"; | |||||
this.btnGen.Size = new System.Drawing.Size(170, 64); | |||||
this.btnGen.TabIndex = 0; | |||||
this.btnGen.Text = "注册"; | |||||
this.btnGen.UseVisualStyleBackColor = true; | |||||
this.btnGen.Click += new System.EventHandler(this.btnGen_Click); | |||||
// | |||||
// txtIdList | |||||
// | |||||
this.txtIdList.Location = new System.Drawing.Point(12, 12); | |||||
this.txtIdList.Multiline = true; | |||||
this.txtIdList.Name = "txtIdList"; | |||||
this.txtIdList.ScrollBars = System.Windows.Forms.ScrollBars.Both; | |||||
this.txtIdList.Size = new System.Drawing.Size(443, 346); | |||||
this.txtIdList.TabIndex = 1; | |||||
// | |||||
// button1 | |||||
// | |||||
this.button1.Location = new System.Drawing.Point(286, 385); | |||||
this.button1.Name = "button1"; | |||||
this.button1.Size = new System.Drawing.Size(170, 64); | |||||
this.button1.TabIndex = 2; | |||||
this.button1.Text = "注销"; | |||||
this.button1.UseVisualStyleBackColor = true; | |||||
this.button1.Click += new System.EventHandler(this.button1_Click); | |||||
// | |||||
// StartForm | |||||
// | |||||
this.AutoScaleDimensions = new System.Drawing.SizeF(11F, 24F); | |||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; | |||||
this.ClientSize = new System.Drawing.Size(468, 514); | |||||
this.Controls.Add(this.button1); | |||||
this.Controls.Add(this.txtIdList); | |||||
this.Controls.Add(this.btnGen); | |||||
this.Name = "StartForm"; | |||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; | |||||
this.Text = "TestForm"; | |||||
this.Load += new System.EventHandler(this.Form1_Load); | |||||
this.ResumeLayout(false); | |||||
this.PerformLayout(); | |||||
} | |||||
#endregion | |||||
private System.Windows.Forms.Button btnGen; | |||||
private System.Windows.Forms.TextBox txtIdList; | |||||
private System.Windows.Forms.Button button1; | |||||
} | |||||
} | |||||
@@ -0,0 +1,74 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.ComponentModel; | |||||
using System.Data; | |||||
using System.Drawing; | |||||
using System.Linq; | |||||
using System.Runtime.InteropServices; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
using System.Windows.Forms; | |||||
namespace WInFormApp | |||||
{ | |||||
public partial class StartForm : Form | |||||
{ | |||||
public StartForm() | |||||
{ | |||||
InitializeComponent(); | |||||
} | |||||
[DllImport("yitidgengo.dll", CallingConvention = CallingConvention.StdCall)] | |||||
public static extern long NextId(); | |||||
[DllImport("yitidgengo.dll", CallingConvention = CallingConvention.StdCall)] | |||||
public static extern long NextId2(); | |||||
[DllImport("yitidgengo.dll", CallingConvention = CallingConvention.StdCall)] | |||||
public static extern long RegisterWorkerId(string ip, int port, string password, int maxWorkerIdNumber); | |||||
//public static extern ulong RegisterWorkerId2(); | |||||
[DllImport("yitidgengo.dll", CallingConvention = CallingConvention.StdCall)] | |||||
public static extern long UnRegisterWorkerId(); | |||||
[DllImport("yitidgen.dll", CallingConvention = CallingConvention.StdCall)] | |||||
public static extern void SetWorkerId(uint workerId); | |||||
[DllImport("yitidgen.dll", CallingConvention = CallingConvention.StdCall)] | |||||
public static extern int Test(); | |||||
[DllImport("yitidgen.dll", CallingConvention = CallingConvention.StdCall)] | |||||
public static extern int GetWorkerId(string ip, int port); | |||||
private void Form1_Load(object sender, EventArgs e) | |||||
{ | |||||
} | |||||
private void btnGen_Click(object sender, EventArgs e) | |||||
{ | |||||
try | |||||
{ | |||||
var ip = "localhost"; | |||||
//txtIdList.Text += RegisterWorkerId(Encoding.UTF8.GetBytes(ip), 6379) + "\r\n"; | |||||
txtIdList.Text += RegisterWorkerId(ip, 6379, "", 4) + "\r\n"; | |||||
//txtIdList.Text += RegisterWorkerId() + "\r\n"; | |||||
//txtIdList.Text += Test() + "\r\n"; | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
txtIdList.Text = ex.Message; | |||||
} | |||||
} | |||||
private void button1_Click(object sender, EventArgs e) | |||||
{ | |||||
UnRegisterWorkerId(); | |||||
// GetWorkerId("localhost", 6379); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,60 @@ | |||||
<root> | |||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> | |||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> | |||||
<xsd:element name="root" msdata:IsDataSet="true"> | |||||
<xsd:complexType> | |||||
<xsd:choice maxOccurs="unbounded"> | |||||
<xsd:element name="metadata"> | |||||
<xsd:complexType> | |||||
<xsd:sequence> | |||||
<xsd:element name="value" type="xsd:string" minOccurs="0" /> | |||||
</xsd:sequence> | |||||
<xsd:attribute name="name" use="required" type="xsd:string" /> | |||||
<xsd:attribute name="type" type="xsd:string" /> | |||||
<xsd:attribute name="mimetype" type="xsd:string" /> | |||||
<xsd:attribute ref="xml:space" /> | |||||
</xsd:complexType> | |||||
</xsd:element> | |||||
<xsd:element name="assembly"> | |||||
<xsd:complexType> | |||||
<xsd:attribute name="alias" type="xsd:string" /> | |||||
<xsd:attribute name="name" type="xsd:string" /> | |||||
</xsd:complexType> | |||||
</xsd:element> | |||||
<xsd:element name="data"> | |||||
<xsd:complexType> | |||||
<xsd:sequence> | |||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> | |||||
</xsd:sequence> | |||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> | |||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> | |||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> | |||||
<xsd:attribute ref="xml:space" /> | |||||
</xsd:complexType> | |||||
</xsd:element> | |||||
<xsd:element name="resheader"> | |||||
<xsd:complexType> | |||||
<xsd:sequence> | |||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||||
</xsd:sequence> | |||||
<xsd:attribute name="name" type="xsd:string" use="required" /> | |||||
</xsd:complexType> | |||||
</xsd:element> | |||||
</xsd:choice> | |||||
</xsd:complexType> | |||||
</xsd:element> | |||||
</xsd:schema> | |||||
<resheader name="resmimetype"> | |||||
<value>text/microsoft-resx</value> | |||||
</resheader> | |||||
<resheader name="version"> | |||||
<value>2.0</value> | |||||
</resheader> | |||||
<resheader name="reader"> | |||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||||
</resheader> | |||||
<resheader name="writer"> | |||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||||
</resheader> | |||||
</root> |
@@ -0,0 +1,19 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop"> | |||||
<PropertyGroup> | |||||
<OutputType>WinExe</OutputType> | |||||
<TargetFramework>net5.0-windows</TargetFramework> | |||||
<UseWindowsForms>true</UseWindowsForms> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<None Remove="yitidgen.dll" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<Content Include="yitidgen.dll"> | |||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | |||||
</Content> | |||||
</ItemGroup> | |||||
</Project> |
@@ -7,6 +7,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yitter.IdGenerator", "Yitte | |||||
EndProject | EndProject | ||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yitter.IdGenTest", "Yitter.IdGenTest\Yitter.IdGenTest.csproj", "{67426F7D-0A3B-4645-B4D7-5487215D3E2B}" | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yitter.IdGenTest", "Yitter.IdGenTest\Yitter.IdGenTest.csproj", "{67426F7D-0A3B-4645-B4D7-5487215D3E2B}" | ||||
EndProject | EndProject | ||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "YitIdGen.WinFormApp", "YitIdGen.WinFormApp\YitIdGen.WinFormApp.csproj", "{1035D82E-3F37-4940-AA32-5D1E0E53AFA5}" | |||||
EndProject | |||||
Global | Global | ||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
Debug|Any CPU = Debug|Any CPU | Debug|Any CPU = Debug|Any CPU | ||||
@@ -21,6 +23,10 @@ Global | |||||
{67426F7D-0A3B-4645-B4D7-5487215D3E2B}.Debug|Any CPU.Build.0 = Debug|Any CPU | {67426F7D-0A3B-4645-B4D7-5487215D3E2B}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||
{67426F7D-0A3B-4645-B4D7-5487215D3E2B}.Release|Any CPU.ActiveCfg = Release|Any CPU | {67426F7D-0A3B-4645-B4D7-5487215D3E2B}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||
{67426F7D-0A3B-4645-B4D7-5487215D3E2B}.Release|Any CPU.Build.0 = Release|Any CPU | {67426F7D-0A3B-4645-B4D7-5487215D3E2B}.Release|Any CPU.Build.0 = Release|Any CPU | ||||
{1035D82E-3F37-4940-AA32-5D1E0E53AFA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{1035D82E-3F37-4940-AA32-5D1E0E53AFA5}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
{1035D82E-3F37-4940-AA32-5D1E0E53AFA5}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
{1035D82E-3F37-4940-AA32-5D1E0E53AFA5}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
EndGlobalSection | EndGlobalSection | ||||
GlobalSection(SolutionProperties) = preSolution | GlobalSection(SolutionProperties) = preSolution | ||||
HideSolutionNode = FALSE | HideSolutionNode = FALSE | ||||
@@ -15,7 +15,6 @@ namespace Yitter.OrgSystem.TestA | |||||
public IList<long> idList = new List<long>(); | public IList<long> idList = new List<long>(); | ||||
private int GenIdCount; | private int GenIdCount; | ||||
private int WorkerId; | private int WorkerId; | ||||
public GenTest(IIdGenerator idGen, int genIdCount, int workerId) | public GenTest(IIdGenerator idGen, int genIdCount, int workerId) | ||||
{ | { | ||||
@@ -55,9 +55,9 @@ namespace Yitter.OrgSystem.TestA | |||||
while (true) | while (true) | ||||
{ | { | ||||
//RunSingle(); | |||||
RunSingle(); | |||||
//CallDll(); | |||||
//Go(options); | //Go(options); | ||||
CallDll(); | |||||
Thread.Sleep(1000); // 每隔1秒执行一次Go | Thread.Sleep(1000); // 每隔1秒执行一次Go | ||||
} | } | ||||
} | } | ||||
@@ -65,13 +65,13 @@ namespace Yitter.OrgSystem.TestA | |||||
//[DllImport("yitidgenc.dll", CallingConvention = CallingConvention.StdCall)] | //[DllImport("yitidgenc.dll", CallingConvention = CallingConvention.StdCall)] | ||||
//public static extern long NextId(); | //public static extern long NextId(); | ||||
[DllImport("yitidgenc.dll", CallingConvention = CallingConvention.StdCall)] | |||||
[DllImport("yitidgengo.dll", CallingConvention = CallingConvention.StdCall)] | |||||
public static extern long NextId(); | public static extern long NextId(); | ||||
[DllImport("yitidgenc.dll", CallingConvention = CallingConvention.StdCall)] | |||||
[DllImport("yitidgen.dll", CallingConvention = CallingConvention.StdCall)] | |||||
public static extern void SetWorkerId(uint workerId); | public static extern void SetWorkerId(uint workerId); | ||||
[DllImport("yitidgenc.dll", CallingConvention = CallingConvention.StdCall)] | |||||
[DllImport("yitidgen.dll", CallingConvention = CallingConvention.StdCall)] | |||||
public static extern int TestId(); | public static extern int TestId(); | ||||
private static void CallDll() | private static void CallDll() | ||||
@@ -1,47 +0,0 @@ | |||||
/* | |||||
* 版权属于:yitter(yitter@126.com) | |||||
* 代码编辑:guoyahao | |||||
* 代码修订:yitter | |||||
* 开源地址:https://gitee.com/yitter/idgenerator | |||||
*/ | |||||
package gen | |||||
import ( | |||||
"sync" | |||||
"yitidgen/contract" | |||||
) | |||||
var ins *YitIdHelper | |||||
var once sync.Once | |||||
type YitIdHelper struct { | |||||
idGenInstance interface { | |||||
NewLong() uint64 | |||||
} | |||||
} | |||||
func GetIns() *YitIdHelper { | |||||
once.Do(func() { | |||||
ins = &YitIdHelper{} | |||||
}) | |||||
return ins | |||||
} | |||||
func (yih *YitIdHelper) GetIdGenInstance() interface{} { | |||||
return yih.idGenInstance | |||||
} | |||||
func (yih *YitIdHelper) SetIdGenerator(options *contract.IdGeneratorOptions) { | |||||
yih.idGenInstance = NewDefaultIdGenerator(options) | |||||
} | |||||
func (yih *YitIdHelper) NextId() uint64 { | |||||
once.Do(func() { | |||||
if yih.idGenInstance == nil { | |||||
options := contract.NewIdGeneratorOptions(1) | |||||
yih.idGenInstance = NewDefaultIdGenerator(options) | |||||
} | |||||
}) | |||||
return yih.idGenInstance.NewLong() | |||||
} |
@@ -1 +1,9 @@ | |||||
module "yitidgen" | |||||
module yitidgen | |||||
go 1.16 | |||||
require ( | |||||
github.com/go-redis/redis v6.15.9+incompatible | |||||
github.com/onsi/ginkgo v1.15.2 // indirect | |||||
github.com/onsi/gomega v1.11.0 // indirect | |||||
) |
@@ -0,0 +1,82 @@ | |||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= | |||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= | |||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= | |||||
github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg= | |||||
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= | |||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | |||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= | |||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= | |||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= | |||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= | |||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= | |||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= | |||||
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= | |||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= | |||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | |||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | |||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= | |||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | |||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= | |||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= | |||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= | |||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= | |||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= | |||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= | |||||
github.com/onsi/ginkgo v1.15.2 h1:l77YT15o814C2qVL47NOyjV/6RbaP7kKdrvZnxQ3Org= | |||||
github.com/onsi/ginkgo v1.15.2/go.mod h1:Dd6YFfwBW84ETqqtL0CPyPXillHgY6XhQH3uuCCTr/o= | |||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= | |||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= | |||||
github.com/onsi/gomega v1.11.0 h1:+CqWgvj0OZycCaqclBD1pxKHAU+tOkHmQIWvDHq2aug= | |||||
github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg= | |||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | |||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | |||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | |||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | |||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= | |||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | |||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | |||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | |||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= | |||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= | |||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U= | |||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= | |||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | |||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | |||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | |||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | |||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | |||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091 h1:DMyOG0U+gKfu8JZzg2UQe9MeaC1X+xQWlAKcRnjxjCw= | |||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | |||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= | |||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | |||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | |||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | |||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= | |||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | |||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | |||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | |||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= | |||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | |||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= | |||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= | |||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= | |||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= | |||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= | |||||
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= | |||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= | |||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | |||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | |||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= | |||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= | |||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= | |||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | |||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | |||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= | |||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= |
@@ -4,7 +4,7 @@ | |||||
* 代码修订:yitter | * 代码修订:yitter | ||||
* 开源地址:https://gitee.com/yitter/idgenerator | * 开源地址:https://gitee.com/yitter/idgenerator | ||||
*/ | */ | ||||
package gen | |||||
package idgen | |||||
import ( | import ( | ||||
"time" | "time" |
@@ -0,0 +1,68 @@ | |||||
/* | |||||
* 版权属于:yitter(yitter@126.com) | |||||
* 代码编辑:guoyahao | |||||
* 代码修订:yitter | |||||
* 开源地址:https://gitee.com/yitter/idgenerator | |||||
*/ | |||||
package idgen | |||||
import ( | |||||
"sync" | |||||
"yitidgen/contract" | |||||
) | |||||
//var yitIdHelper *YitIdHelper | |||||
//var once sync.Once | |||||
var idGenerator *DefaultIdGenerator | |||||
var singletonMutex sync.Mutex | |||||
type YitIdHelper struct { | |||||
idGenInstance interface { | |||||
NewLong() uint64 | |||||
} | |||||
} | |||||
// | |||||
//func GetIns() *YitIdHelper { | |||||
// once.Do(func() { | |||||
// yitIdHelper = &YitIdHelper{} | |||||
// }) | |||||
// return yitIdHelper | |||||
//} | |||||
// | |||||
//func (yih *YitIdHelper) GetIdGenInstance() interface{} { | |||||
// return yih.idGenInstance | |||||
//} | |||||
// | |||||
//func (yih *YitIdHelper) SetIdGenerator(options *contract.IdGeneratorOptions) { | |||||
// yih.idGenInstance = NewDefaultIdGenerator(options) | |||||
//} | |||||
// | |||||
//func (yih *YitIdHelper) NextId() uint64 { | |||||
// once.Do(func() { | |||||
// if yih.idGenInstance == nil { | |||||
// options := contract.NewIdGeneratorOptions(1) | |||||
// yih.idGenInstance = NewDefaultIdGenerator(options) | |||||
// } | |||||
// }) | |||||
// | |||||
// return yih.idGenInstance.NewLong() | |||||
//} | |||||
func SetIdGenerator(options *contract.IdGeneratorOptions) { | |||||
singletonMutex.Lock() | |||||
idGenerator = NewDefaultIdGenerator(options) | |||||
singletonMutex.Unlock() | |||||
} | |||||
func NextId() uint64 { | |||||
if idGenerator == nil { | |||||
singletonMutex.Lock() | |||||
options := contract.NewIdGeneratorOptions(1) | |||||
idGenerator = NewDefaultIdGenerator(options) | |||||
singletonMutex.Unlock() | |||||
} | |||||
return idGenerator.NewLong() | |||||
} |
@@ -0,0 +1,67 @@ | |||||
package main | |||||
import ( | |||||
"C" | |||||
"fmt" | |||||
"time" | |||||
"yitidgen/contract" | |||||
"yitidgen/idgen" | |||||
"yitidgen/regworkerid" | |||||
) | |||||
//export SetOptions | |||||
func SetOptions(workerId uint16) { | |||||
var options = contract.NewIdGeneratorOptions(workerId) | |||||
idgen.SetIdGenerator(options) | |||||
} | |||||
//export NextId | |||||
func NextId() uint64 { | |||||
return idgen.NextId() | |||||
} | |||||
//export RegisterWorkerId | |||||
func RegisterWorkerId(ip *C.char, port int, password *C.char, maxWorkerId int) int { | |||||
return regworkerid.RegisterWorkerId(C.GoString(ip), port, C.GoString(password), maxWorkerId) | |||||
} | |||||
//export UnRegisterWorkerId | |||||
func UnRegisterWorkerId() { | |||||
regworkerid.UnRegisterWorkerId() | |||||
} | |||||
func main() { | |||||
// 方法一:直接采用默认方法生成一个Id | |||||
fmt.Println("生成的Id:", idgen.NextId()) | |||||
fmt.Println("生成的Id:", regworkerid.RegisterWorkerId("localhost", 6379, "", 4)) | |||||
return | |||||
// 方法二:自定义参数 | |||||
var options = contract.NewIdGeneratorOptions(1) | |||||
options.WorkerIdBitLength = 6 | |||||
options.SeqBitLength = 6 | |||||
options.TopOverCostCount = 2000 | |||||
options.BaseTime = time.Date(2020, 2, 20, 2, 20, 2, 20, time.UTC).UnixNano() / 1e6 | |||||
idgen.SetIdGenerator(options) | |||||
var genCount = 50000 | |||||
for { | |||||
var begin = time.Now().UnixNano() / 1e6 | |||||
for i := 0; i < genCount; i++ { | |||||
idgen.NextId() | |||||
} | |||||
var end = time.Now().UnixNano() / 1e6 | |||||
fmt.Println(end - begin) | |||||
time.Sleep(time.Duration(1000) * time.Millisecond) | |||||
} | |||||
} | |||||
// go build -o target\yitidgengo.dll -buildmode=c-shared main.go | |||||
//var yid = idgen.YitIdHelper{} | |||||
//yid.SetIdGenerator(options) | |||||
//fmt.Println(yid.NextId()) |
@@ -0,0 +1,230 @@ | |||||
package regworkerid | |||||
import ( | |||||
"fmt" | |||||
"github.com/go-redis/redis" | |||||
"strconv" | |||||
"sync" | |||||
"time" | |||||
) | |||||
var Client *redis.Client | |||||
var _usingWorkerId int = -1 | |||||
var _maxWorkerId int = 0 | |||||
var _loopCount int = 0 | |||||
var _liftIndex int = -1 | |||||
var _workerIdLock sync.Mutex | |||||
const CurrentWidIndexKey string = "IdGen:WorkerId:Index" | |||||
const WidKeyPrefix string = "IdGen:WorkerId:Value:" | |||||
const WorkerIdFlag = "Y" // WorkerId 存储标记 | |||||
const WorkerIdLifeTimeSeconds = 15 // WorkerIdFlag 有效期(单位秒,最好是3的倍数) | |||||
const Log = false | |||||
func UnRegisterWorkerId() { | |||||
if _usingWorkerId < 0 { | |||||
return | |||||
} | |||||
_workerIdLock.Lock() | |||||
Client.Del(WidKeyPrefix + strconv.Itoa(_usingWorkerId)) | |||||
_usingWorkerId = -1 | |||||
_liftIndex = -1 | |||||
_workerIdLock.Unlock() | |||||
} | |||||
func RegisterWorkerId(ip string, port int, password string, maxWorkerId int) int { | |||||
// maxWorkerId不能小于0 | |||||
if maxWorkerId < 0 { | |||||
return -1 | |||||
} | |||||
// 如果当前已注册过 WorkerId,则先注销,并终止先前的自动续期线程 | |||||
if _usingWorkerId > -1 { | |||||
UnRegisterWorkerId() | |||||
} | |||||
_maxWorkerId = maxWorkerId | |||||
Client = redis.NewClient(&redis.Options{ | |||||
Addr: string(ip) + ":" + strconv.Itoa(port), | |||||
PoolSize: 1000, | |||||
ReadTimeout: time.Millisecond * time.Duration(100), | |||||
WriteTimeout: time.Millisecond * time.Duration(100), | |||||
IdleTimeout: time.Second * time.Duration(60), | |||||
Password: password, | |||||
}) | |||||
_, err := Client.Ping().Result() | |||||
if err != nil { | |||||
panic("init redis error") | |||||
} else { | |||||
if Log { | |||||
fmt.Println("init redis ok") | |||||
} | |||||
} | |||||
_loopCount = 0 | |||||
return getNextWorkerId() | |||||
} | |||||
func getNextWorkerId() int { | |||||
// 获取当前 WorkerIdIndex | |||||
// var currentId = int(Client.Incr(CurrentWidIndexKey).Val()) | |||||
r, err := Client.Incr(CurrentWidIndexKey).Result() | |||||
if err != nil { | |||||
return 0 | |||||
} | |||||
currentId := int(r) | |||||
if Log { | |||||
fmt.Println("Begin currentId:" + strconv.Itoa(currentId)) | |||||
} | |||||
// 如果 Index 大于最大值,则重置 | |||||
if currentId > _maxWorkerId { | |||||
if canReset() { | |||||
// 当前应用获得重置 WorkerIdIndex 的权限 | |||||
setWorkerIdIndex(-1) | |||||
endReset() // 此步有可能不被执行? | |||||
_loopCount++ | |||||
// 超过一定次数,直接终止操作 | |||||
if _loopCount > 10 { | |||||
return -1 | |||||
} | |||||
// if _loopCount > 2 { | |||||
// 如果超过2个循环,则暂停1s | |||||
time.Sleep(time.Duration(500*_loopCount) * time.Millisecond) | |||||
//_loopCount = 0 | |||||
//} | |||||
if Log { | |||||
fmt.Println("canReset loop") | |||||
} | |||||
return getNextWorkerId() | |||||
} else { | |||||
// 如果有其它应用正在编辑,则本应用暂停1s后,再继续 | |||||
time.Sleep(time.Duration(1000) * time.Millisecond) | |||||
if Log { | |||||
fmt.Println("not canReset loop") | |||||
} | |||||
return getNextWorkerId() | |||||
} | |||||
} | |||||
if Log { | |||||
fmt.Println("currentId:" + strconv.Itoa(currentId)) | |||||
} | |||||
if isAvailable(currentId) { | |||||
if Log { | |||||
fmt.Println("AA: isAvailable:" + strconv.Itoa(currentId)) | |||||
} | |||||
// 最新获得的 WorkerIdIndex,在 redis 中是可用状态 | |||||
setWorkerIdFlag(currentId) | |||||
_usingWorkerId = currentId | |||||
// 获取到可用 WorkerId 后,启用新线程,每隔 1/3个 WorkerIdLifeTimeSeconds 时间,向服务器续期(延长一次 LifeTime) | |||||
_liftIndex++ | |||||
go extendWorkerIdLifeTime(_liftIndex) | |||||
return currentId | |||||
} else { | |||||
if Log { | |||||
fmt.Println("BB: not isAvailable:" + strconv.Itoa(currentId)) | |||||
} | |||||
// 最新获得的 WorkerIdIndex,在 redis 中是不可用状态,则继续下一个 WorkerIdIndex | |||||
return getNextWorkerId() | |||||
} | |||||
} | |||||
func extendWorkerIdLifeTime(lifeIndex int) { | |||||
var index = lifeIndex | |||||
for { | |||||
time.Sleep(time.Duration(WorkerIdLifeTimeSeconds/3) * time.Millisecond) | |||||
_workerIdLock.Lock() | |||||
if index != _liftIndex { | |||||
// 如果临时变量 index 不等于 全局变量 _liftIndex,表明全局状态被修改,当前线程可终止 | |||||
break | |||||
} | |||||
// 已经被注销,则终止(此步是上一步的二次验证) | |||||
if _usingWorkerId < 0 { | |||||
break | |||||
} | |||||
extendWorkerIdFlag(_usingWorkerId) | |||||
_workerIdLock.Unlock() | |||||
} | |||||
} | |||||
func get(key string) (string, bool) { | |||||
r, err := Client.Get(key).Result() | |||||
if err != nil { | |||||
return "", false | |||||
} | |||||
return r, true | |||||
} | |||||
func set(key string, val string, expTime int32) { | |||||
Client.Set(key, val, time.Duration(expTime)*time.Second) | |||||
} | |||||
func setWorkerIdIndex(val int) { | |||||
Client.Set(CurrentWidIndexKey, val, 0) | |||||
} | |||||
func setWorkerIdFlag(index int) { | |||||
Client.Set(WidKeyPrefix+strconv.Itoa(index), WorkerIdFlag, time.Duration(WorkerIdLifeTimeSeconds)*time.Second) | |||||
} | |||||
func extendWorkerIdFlag(index int) { | |||||
Client.Expire(WidKeyPrefix+strconv.Itoa(index), time.Duration(WorkerIdLifeTimeSeconds)*time.Second) | |||||
} | |||||
func canReset() bool { | |||||
r, err := Client.Incr(WidKeyPrefix + "Edit").Result() | |||||
if err != nil { | |||||
return false | |||||
} | |||||
if Log { | |||||
fmt.Println("canReset:" + string(r)) | |||||
} | |||||
return r != 1 | |||||
} | |||||
func endReset() { | |||||
// Client.Set(WidKeyPrefix+"Edit", 0, time.Duration(2)*time.Second) | |||||
Client.Set(WidKeyPrefix+"Edit", 0, 0) | |||||
} | |||||
func getWorkerIdFlag(index int) (string, bool) { | |||||
r, err := Client.Get(WidKeyPrefix + strconv.Itoa(index)).Result() | |||||
if err != nil { | |||||
return "", false | |||||
} | |||||
return r, true | |||||
} | |||||
func isAvailable(index int) bool { | |||||
r, err := Client.Get(WidKeyPrefix + strconv.Itoa(index)).Result() | |||||
if Log { | |||||
fmt.Println("XX isAvailable:" + r) | |||||
fmt.Println("YY isAvailable:" + err.Error()) | |||||
} | |||||
if err != nil { | |||||
if err.Error() == "redis: nil" { | |||||
return true | |||||
} | |||||
return false | |||||
} | |||||
return r != WorkerIdFlag | |||||
} |
@@ -0,0 +1,75 @@ | |||||
/* Code generated by cmd/cgo; DO NOT EDIT. */ | |||||
/* package command-line-arguments */ | |||||
#line 1 "cgo-builtin-export-prolog" | |||||
#include <stddef.h> /* for ptrdiff_t below */ | |||||
#ifndef GO_CGO_EXPORT_PROLOGUE_H | |||||
#define GO_CGO_EXPORT_PROLOGUE_H | |||||
#ifndef GO_CGO_GOSTRING_TYPEDEF | |||||
typedef struct { const char *p; ptrdiff_t n; } _GoString_; | |||||
#endif | |||||
#endif | |||||
/* Start of preamble from import "C" comments. */ | |||||
/* End of preamble from import "C" comments. */ | |||||
/* Start of boilerplate cgo prologue. */ | |||||
#line 1 "cgo-gcc-export-header-prolog" | |||||
#ifndef GO_CGO_PROLOGUE_H | |||||
#define GO_CGO_PROLOGUE_H | |||||
typedef signed char GoInt8; | |||||
typedef unsigned char GoUint8; | |||||
typedef short GoInt16; | |||||
typedef unsigned short GoUint16; | |||||
typedef int GoInt32; | |||||
typedef unsigned int GoUint32; | |||||
typedef long long GoInt64; | |||||
typedef unsigned long long GoUint64; | |||||
typedef GoInt64 GoInt; | |||||
typedef GoUint64 GoUint; | |||||
typedef __SIZE_TYPE__ GoUintptr; | |||||
typedef float GoFloat32; | |||||
typedef double GoFloat64; | |||||
typedef float _Complex GoComplex64; | |||||
typedef double _Complex GoComplex128; | |||||
/* | |||||
static assertion to make sure the file is being used on architecture | |||||
at least with matching size of GoInt. | |||||
*/ | |||||
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1]; | |||||
#ifndef GO_CGO_GOSTRING_TYPEDEF | |||||
typedef _GoString_ GoString; | |||||
#endif | |||||
typedef void *GoMap; | |||||
typedef void *GoChan; | |||||
typedef struct { void *t; void *v; } GoInterface; | |||||
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice; | |||||
#endif | |||||
/* End of boilerplate cgo prologue. */ | |||||
#ifdef __cplusplus | |||||
extern "C" { | |||||
#endif | |||||
extern __declspec(dllexport) GoUint64 NextId(); | |||||
#ifdef __cplusplus | |||||
} | |||||
#endif |
@@ -0,0 +1,75 @@ | |||||
/* Code generated by cmd/cgo; DO NOT EDIT. */ | |||||
/* package command-line-arguments */ | |||||
#line 1 "cgo-builtin-export-prolog" | |||||
#include <stddef.h> /* for ptrdiff_t below */ | |||||
#ifndef GO_CGO_EXPORT_PROLOGUE_H | |||||
#define GO_CGO_EXPORT_PROLOGUE_H | |||||
#ifndef GO_CGO_GOSTRING_TYPEDEF | |||||
typedef struct { const char *p; ptrdiff_t n; } _GoString_; | |||||
#endif | |||||
#endif | |||||
/* Start of preamble from import "C" comments. */ | |||||
/* End of preamble from import "C" comments. */ | |||||
/* Start of boilerplate cgo prologue. */ | |||||
#line 1 "cgo-gcc-export-header-prolog" | |||||
#ifndef GO_CGO_PROLOGUE_H | |||||
#define GO_CGO_PROLOGUE_H | |||||
typedef signed char GoInt8; | |||||
typedef unsigned char GoUint8; | |||||
typedef short GoInt16; | |||||
typedef unsigned short GoUint16; | |||||
typedef int GoInt32; | |||||
typedef unsigned int GoUint32; | |||||
typedef long long GoInt64; | |||||
typedef unsigned long long GoUint64; | |||||
typedef GoInt64 GoInt; | |||||
typedef GoUint64 GoUint; | |||||
typedef __SIZE_TYPE__ GoUintptr; | |||||
typedef float GoFloat32; | |||||
typedef double GoFloat64; | |||||
typedef float _Complex GoComplex64; | |||||
typedef double _Complex GoComplex128; | |||||
/* | |||||
static assertion to make sure the file is being used on architecture | |||||
at least with matching size of GoInt. | |||||
*/ | |||||
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1]; | |||||
#ifndef GO_CGO_GOSTRING_TYPEDEF | |||||
typedef _GoString_ GoString; | |||||
#endif | |||||
typedef void *GoMap; | |||||
typedef void *GoChan; | |||||
typedef struct { void *t; void *v; } GoInterface; | |||||
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice; | |||||
#endif | |||||
/* End of boilerplate cgo prologue. */ | |||||
#ifdef __cplusplus | |||||
extern "C" { | |||||
#endif | |||||
extern __declspec(dllexport) GoUint64 NextId(); | |||||
#ifdef __cplusplus | |||||
} | |||||
#endif |
@@ -0,0 +1,78 @@ | |||||
/* Code generated by cmd/cgo; DO NOT EDIT. */ | |||||
/* package command-line-arguments */ | |||||
#line 1 "cgo-builtin-export-prolog" | |||||
#include <stddef.h> /* for ptrdiff_t below */ | |||||
#ifndef GO_CGO_EXPORT_PROLOGUE_H | |||||
#define GO_CGO_EXPORT_PROLOGUE_H | |||||
#ifndef GO_CGO_GOSTRING_TYPEDEF | |||||
typedef struct { const char *p; ptrdiff_t n; } _GoString_; | |||||
#endif | |||||
#endif | |||||
/* Start of preamble from import "C" comments. */ | |||||
/* End of preamble from import "C" comments. */ | |||||
/* Start of boilerplate cgo prologue. */ | |||||
#line 1 "cgo-gcc-export-header-prolog" | |||||
#ifndef GO_CGO_PROLOGUE_H | |||||
#define GO_CGO_PROLOGUE_H | |||||
typedef signed char GoInt8; | |||||
typedef unsigned char GoUint8; | |||||
typedef short GoInt16; | |||||
typedef unsigned short GoUint16; | |||||
typedef int GoInt32; | |||||
typedef unsigned int GoUint32; | |||||
typedef long long GoInt64; | |||||
typedef unsigned long long GoUint64; | |||||
typedef GoInt64 GoInt; | |||||
typedef GoUint64 GoUint; | |||||
typedef __SIZE_TYPE__ GoUintptr; | |||||
typedef float GoFloat32; | |||||
typedef double GoFloat64; | |||||
typedef float _Complex GoComplex64; | |||||
typedef double _Complex GoComplex128; | |||||
/* | |||||
static assertion to make sure the file is being used on architecture | |||||
at least with matching size of GoInt. | |||||
*/ | |||||
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1]; | |||||
#ifndef GO_CGO_GOSTRING_TYPEDEF | |||||
typedef _GoString_ GoString; | |||||
#endif | |||||
typedef void *GoMap; | |||||
typedef void *GoChan; | |||||
typedef struct { void *t; void *v; } GoInterface; | |||||
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice; | |||||
#endif | |||||
/* End of boilerplate cgo prologue. */ | |||||
#ifdef __cplusplus | |||||
extern "C" { | |||||
#endif | |||||
extern __declspec(dllexport) void SetOptions(GoUint16 workerId); | |||||
extern __declspec(dllexport) GoUint64 NextId(); | |||||
extern __declspec(dllexport) GoInt RegisterWorkerId(char* ip, GoInt port, char* password, GoInt maxWorkerId); | |||||
extern __declspec(dllexport) void UnRegisterWorkerId(); | |||||
#ifdef __cplusplus | |||||
} | |||||
#endif |
@@ -1,43 +0,0 @@ | |||||
package main | |||||
import ( | |||||
"C" | |||||
"fmt" | |||||
"time" | |||||
"yitidgen/contract" | |||||
"yitidgen/gen" | |||||
) | |||||
//export NextId | |||||
func NextId() uint64{ | |||||
return gen.GetIns().NextId() | |||||
} | |||||
func main() { | |||||
// 方法一:直接采用默认方法生成一个Id | |||||
var yid = gen.YitIdHelper{} | |||||
fmt.Println(yid.NextId()) | |||||
// 方法二:自定义参数 | |||||
var options = contract.NewIdGeneratorOptions(1) | |||||
//options.WorkerIdBitLength = 6 | |||||
//options.SeqBitLength = 6 | |||||
//options.TopOverCostCount = 2000 | |||||
//options.BaseTime = time.Date(2020, 2, 20, 2, 20, 2, 20, time.UTC).UnixNano() / 1e6 | |||||
yid.SetIdGenerator(options) | |||||
var times = 50000 | |||||
for { | |||||
var begin = time.Now().UnixNano() / 1e6 | |||||
for i := 0; i < times; i++ { | |||||
yid.NextId() | |||||
} | |||||
var end = time.Now().UnixNano() / 1e6 | |||||
fmt.Println(end - begin) | |||||
time.Sleep(time.Duration(1000) * time.Millisecond) | |||||
} | |||||
} |
@@ -1,4 +0,0 @@ | |||||
# idgenerator | |||||
something is going on. | |||||
@@ -1,4 +1,4 @@ | |||||
# IdGenerator SnowFlake 雪花算法 原生多语言版本 顶尖优化 超强效能 | |||||
# 唯一ID生成器 IdGenerator SnowFlake 雪花算法 原生多语言源码 | |||||
## 介绍 | ## 介绍 | ||||
@@ -8,6 +8,8 @@ | |||||
3.原生支持 C#/Java/Go/Rust/C 等语言,并由 Rust 提供 PHP、Python、Node.js、Ruby 等语言多线程安全调用库(FFI)。 | 3.原生支持 C#/Java/Go/Rust/C 等语言,并由 Rust 提供 PHP、Python、Node.js、Ruby 等语言多线程安全调用库(FFI)。 | ||||
4.支持单服务部署、多服务部署、容器自动化服务 | |||||
## 技术支持 | ## 技术支持 | ||||
@@ -27,13 +29,13 @@ QQ群:646049993 | |||||
4.如果这样的主键值太长,超过前端 JS Number 类型最大值,须把 Long 型转换为 String 型,你会觉得有点沮丧。 | 4.如果这样的主键值太长,超过前端 JS Number 类型最大值,须把 Long 型转换为 String 型,你会觉得有点沮丧。 | ||||
5.哪怕 Guid 能自增,但占用空间大,索引速度慢,所以你也不想用它。 | |||||
5.尽管 Guid 能自增,但占用空间大,索引速度慢,你也不想用它。 | |||||
6.你的应用实例可能超过50个,每个并发请求可达10W/s。 | |||||
6.应用实例可能超过50个,每个并发请求可达10W/s。 | |||||
7.在容器环境部署应用(水平扩展、自动伸缩)。 | 7.在容器环境部署应用(水平扩展、自动伸缩)。 | ||||
8.你可不想 Id 生成器依赖 redis 的自增操作。 | |||||
8.不想依赖 redis 的自增操作。 | |||||
9.你希望系统运行 100 年以上。 | 9.你希望系统运行 100 年以上。 | ||||
@@ -164,7 +166,15 @@ ID示例(基于默认配置): | |||||
7.不要修改核心算法。本算法内部参数较多,逻辑较为复杂,在你尚未掌握核心逻辑时,请勿尝试修改核心代码且用于生产环境,除非通过大量细致、科学的测试验证。 | 7.不要修改核心算法。本算法内部参数较多,逻辑较为复杂,在你尚未掌握核心逻辑时,请勿尝试修改核心代码且用于生产环境,除非通过大量细致、科学的测试验证。 | ||||
#### 大型分布式集成 | |||||
#### 自动/手动 设置 WorkerId | |||||
1.如果Id生成服务是明确的,可在初始化时,手动设置 WorkerId。 | |||||
2.如果Id生成服务是不明确的,如容器环境:动态的、自动执行、生命周期完全自动化,可在初始化时通过Redis,自动申请 WorkerId,详见“Tools/AutoRegisterWorkerId” | |||||
#### 其它分布式集成 | |||||
1.可增加 WorkerIdBitLength 到最大20,支持 1,048,576 个节点,且不影响上述并发性能。[算法支持] | 1.可增加 WorkerIdBitLength 到最大20,支持 1,048,576 个节点,且不影响上述并发性能。[算法支持] | ||||
@@ -1,11 +1,28 @@ | |||||
# This file is automatically @generated by Cargo. | # This file is automatically @generated by Cargo. | ||||
# It is not intended for manual editing. | # It is not intended for manual editing. | ||||
[[package]] | |||||
name = "async-trait" | |||||
version = "0.1.48" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
checksum = "36ea56748e10732c49404c153638a15ec3d6211ec5ff35d9bb20e13b93576adf" | |||||
dependencies = [ | |||||
"proc-macro2", | |||||
"quote", | |||||
"syn", | |||||
] | |||||
[[package]] | [[package]] | ||||
name = "autocfg" | name = "autocfg" | ||||
version = "1.0.1" | version = "1.0.1" | ||||
source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" | checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" | ||||
[[package]] | |||||
name = "bytes" | |||||
version = "1.0.1" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" | |||||
[[package]] | [[package]] | ||||
name = "chrono" | name = "chrono" | ||||
version = "0.4.19" | version = "0.4.19" | ||||
@@ -19,6 +36,49 @@ dependencies = [ | |||||
"winapi", | "winapi", | ||||
] | ] | ||||
[[package]] | |||||
name = "combine" | |||||
version = "4.5.2" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
checksum = "cc4369b5e4c0cddf64ad8981c0111e7df4f7078f4d6ba98fb31f2e17c4c57b7e" | |||||
dependencies = [ | |||||
"bytes", | |||||
"memchr", | |||||
] | |||||
[[package]] | |||||
name = "dtoa" | |||||
version = "0.4.8" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" | |||||
[[package]] | |||||
name = "form_urlencoded" | |||||
version = "1.0.1" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" | |||||
dependencies = [ | |||||
"matches", | |||||
"percent-encoding", | |||||
] | |||||
[[package]] | |||||
name = "idna" | |||||
version = "0.2.2" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
checksum = "89829a5d69c23d348314a7ac337fe39173b61149a9864deabd260983aed48c21" | |||||
dependencies = [ | |||||
"matches", | |||||
"unicode-bidi", | |||||
"unicode-normalization", | |||||
] | |||||
[[package]] | |||||
name = "itoa" | |||||
version = "0.4.7" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" | |||||
[[package]] | [[package]] | ||||
name = "lazy_static" | name = "lazy_static" | ||||
version = "1.4.0" | version = "1.4.0" | ||||
@@ -31,6 +91,18 @@ version = "0.2.90" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
checksum = "ba4aede83fc3617411dc6993bc8c70919750c1c257c6ca6a502aed6e0e2394ae" | checksum = "ba4aede83fc3617411dc6993bc8c70919750c1c257c6ca6a502aed6e0e2394ae" | ||||
[[package]] | |||||
name = "matches" | |||||
version = "0.1.8" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" | |||||
[[package]] | |||||
name = "memchr" | |||||
version = "2.3.4" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" | |||||
[[package]] | [[package]] | ||||
name = "num-integer" | name = "num-integer" | ||||
version = "0.1.44" | version = "0.1.44" | ||||
@@ -50,6 +122,62 @@ dependencies = [ | |||||
"autocfg", | "autocfg", | ||||
] | ] | ||||
[[package]] | |||||
name = "percent-encoding" | |||||
version = "2.1.0" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" | |||||
[[package]] | |||||
name = "proc-macro2" | |||||
version = "1.0.24" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" | |||||
dependencies = [ | |||||
"unicode-xid", | |||||
] | |||||
[[package]] | |||||
name = "quote" | |||||
version = "1.0.9" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" | |||||
dependencies = [ | |||||
"proc-macro2", | |||||
] | |||||
[[package]] | |||||
name = "redis" | |||||
version = "0.20.0" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
checksum = "eeb8f8d059ead7805e171fc22de8348a3d611c0f985aaa4f5cf6c0dfc7645407" | |||||
dependencies = [ | |||||
"async-trait", | |||||
"combine", | |||||
"dtoa", | |||||
"itoa", | |||||
"percent-encoding", | |||||
"sha1", | |||||
"url", | |||||
] | |||||
[[package]] | |||||
name = "sha1" | |||||
version = "0.6.0" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" | |||||
[[package]] | |||||
name = "syn" | |||||
version = "1.0.67" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
checksum = "6498a9efc342871f91cc2d0d694c674368b4ceb40f62b65a7a08c3792935e702" | |||||
dependencies = [ | |||||
"proc-macro2", | |||||
"quote", | |||||
"unicode-xid", | |||||
] | |||||
[[package]] | [[package]] | ||||
name = "time" | name = "time" | ||||
version = "0.1.44" | version = "0.1.44" | ||||
@@ -61,6 +189,57 @@ dependencies = [ | |||||
"winapi", | "winapi", | ||||
] | ] | ||||
[[package]] | |||||
name = "tinyvec" | |||||
version = "1.1.1" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
checksum = "317cca572a0e89c3ce0ca1f1bdc9369547fe318a683418e42ac8f59d14701023" | |||||
dependencies = [ | |||||
"tinyvec_macros", | |||||
] | |||||
[[package]] | |||||
name = "tinyvec_macros" | |||||
version = "0.1.0" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" | |||||
[[package]] | |||||
name = "unicode-bidi" | |||||
version = "0.3.4" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" | |||||
dependencies = [ | |||||
"matches", | |||||
] | |||||
[[package]] | |||||
name = "unicode-normalization" | |||||
version = "0.1.17" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
checksum = "07fbfce1c8a97d547e8b5334978438d9d6ec8c20e38f56d4a4374d181493eaef" | |||||
dependencies = [ | |||||
"tinyvec", | |||||
] | |||||
[[package]] | |||||
name = "unicode-xid" | |||||
version = "0.2.1" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" | |||||
[[package]] | |||||
name = "url" | |||||
version = "2.2.1" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
checksum = "9ccd964113622c8e9322cfac19eb1004a07e636c545f325da085d5cdde6f1f8b" | |||||
dependencies = [ | |||||
"form_urlencoded", | |||||
"idna", | |||||
"matches", | |||||
"percent-encoding", | |||||
] | |||||
[[package]] | [[package]] | ||||
name = "wasi" | name = "wasi" | ||||
version = "0.10.0+wasi-snapshot-preview1" | version = "0.10.0+wasi-snapshot-preview1" | ||||
@@ -95,4 +274,6 @@ version = "1.0.0" | |||||
dependencies = [ | dependencies = [ | ||||
"chrono", | "chrono", | ||||
"lazy_static", | "lazy_static", | ||||
"libc", | |||||
"redis", | |||||
] | ] |
@@ -9,6 +9,15 @@ edition = "2018" | |||||
[dependencies] | [dependencies] | ||||
chrono = "0.4.10" | chrono = "0.4.10" | ||||
lazy_static = "1.4.0" | lazy_static = "1.4.0" | ||||
#simple_redis = "*" | |||||
redis = "0.20.0" | |||||
libc="*" | |||||
#actix = "0.9.0" | |||||
#actix-web = "2.0" | |||||
#actix-rt = "1.0" | |||||
#actix-redis = "0.8.0" | |||||
#redis-async = "0.6.1" | |||||
[lib] | [lib] | ||||
name = "yitidgen" | name = "yitidgen" | ||||
@@ -3,6 +3,23 @@ mod yitgen; | |||||
use yitgen::gen::YitIdHelper; | use yitgen::gen::YitIdHelper; | ||||
use yitgen::contract::*; | use yitgen::contract::*; | ||||
#[macro_use] | |||||
extern crate lazy_static; | |||||
extern crate redis; | |||||
extern crate libc; | |||||
use redis::Commands; | |||||
use libc::{c_char, uint32_t}; | |||||
use std::ffi::{CStr, CString}; | |||||
use std::str; | |||||
lazy_static! { | |||||
//static ref TestValue: Vec<i32> = vec!(0); | |||||
// static ref MAP: HashMap<u32, String> = HashMap::new(); | |||||
} | |||||
// #[export_name = "SetIdGenerator"] | // #[export_name = "SetIdGenerator"] | ||||
#[no_mangle] | #[no_mangle] | ||||
pub extern "C" fn SetIdGenerator(options: IdGeneratorOptions) { | pub extern "C" fn SetIdGenerator(options: IdGeneratorOptions) { | ||||
@@ -19,3 +36,64 @@ pub extern "C" fn NextId() -> i64 { | |||||
YitIdHelper::NextId() | YitIdHelper::NextId() | ||||
} | } | ||||
static mut TestValue: i32 = 0; | |||||
#[no_mangle] | |||||
pub extern "C" fn Test() -> i32 { | |||||
unsafe { | |||||
TestValue += 1; | |||||
return TestValue; | |||||
} | |||||
} | |||||
#[no_mangle] | |||||
pub extern "C" fn GetWorkerId(ip: *const c_char, port: i32) -> redis::RedisResult<isize> { | |||||
// let c_str = unsafe { | |||||
// assert!(!ip.is_null()); | |||||
// CStr::from_ptr(ip) | |||||
// }; | |||||
// | |||||
// let r_str = c_str.to_str(); | |||||
// connect to redis | |||||
// let client = redis::Client::open(format!("redis://{}:{}/", String::from(r_str).to_string(), port))?; | |||||
let client = redis::Client::open(format!("redis://localhost:{}/", port))?; | |||||
let mut con = client.get_connection()?; | |||||
// throw away the result, just make sure it does not fail | |||||
unsafe { | |||||
let _: () = con.set("my_key111", TestValue.clone())?; | |||||
} | |||||
con.get("my_key") | |||||
// read back the key and return it. Because the return value | |||||
// from the function is a result for integer this will automatically | |||||
// convert into one. | |||||
// | |||||
// match simple_redis::create(&format!("redis://{}:{}/", ip, port)) { | |||||
// Ok(mut client) => { | |||||
// println!("Created Redis Client"); | |||||
// | |||||
// let valueString = TestValue.to_string(); | |||||
// let valueString2 = (*TestValue).to_string(); | |||||
// | |||||
// match client.set("my_key", valueString) { | |||||
// Err(error) => println!("Unable to set value in Redis: {}", error), | |||||
// _ => println!("Value set in Redis") | |||||
// }; | |||||
// | |||||
// match client.set("my_key2", valueString2) { | |||||
// Err(error) => println!("Unable to set value in Redis: {}", error), | |||||
// _ => println!("Value set in Redis") | |||||
// }; | |||||
// | |||||
// match client.quit() { | |||||
// Err(error) => println!("Error: {}", error), | |||||
// _ => println!("Connection Closed.") | |||||
// } | |||||
// } | |||||
// Err(error) => println!("Unable to create Redis client: {}", error) | |||||
// } | |||||
//return 1; | |||||
} |
@@ -6,6 +6,7 @@ use std::thread; | |||||
use chrono::Utc; | use chrono::Utc; | ||||
use std::time::Duration; | use std::time::Duration; | ||||
fn main() { | fn main() { | ||||
println!("Hello, world! Rust"); | println!("Hello, world! Rust"); | ||||
@@ -22,6 +23,8 @@ fn main() { | |||||
//... 可以继续设置其它 options 参数 | //... 可以继续设置其它 options 参数 | ||||
YitIdHelper::SetIdGenerator(options); | YitIdHelper::SetIdGenerator(options); | ||||
set_redis(); | |||||
// 以下开始测试生成数据,默认5W,单线程,可以修改 multiThread=true 启用多线程。 | // 以下开始测试生成数据,默认5W,单线程,可以修改 multiThread=true 启用多线程。 | ||||
loop { | loop { | ||||
let mut i = 0; | let mut i = 0; | ||||
@@ -51,3 +54,24 @@ fn main() { | |||||
} | } | ||||
} | } | ||||
fn set_redis() { | |||||
// match simple_redis::create("redis://127.0.0.1:6379/") { | |||||
// Ok(mut client) => { | |||||
// println!("Created Redis Client"); | |||||
// | |||||
// match client.set("my_key", "my_value") { | |||||
// Err(error) => println!("Unable to set value in Redis: {}", error), | |||||
// _ => println!("Value set in Redis") | |||||
// }; | |||||
// | |||||
// match client.quit() { | |||||
// Err(error) => println!("Error: {}", error), | |||||
// _ => println!("Connection Closed.") | |||||
// } | |||||
// }, | |||||
// Err(error) => println!("Unable to create Redis client: {}", error) | |||||
// } | |||||
} | |||||
@@ -6,7 +6,7 @@ use super::super::contract::*; | |||||
use std::{thread}; | use std::{thread}; | ||||
use chrono::Utc; | use chrono::Utc; | ||||
use std::thread::sleep; | use std::thread::sleep; | ||||
use lazy_static::lazy_static; | |||||
// use lazy_static::lazy_static; | |||||
pub struct SnowWorkerM1 { | pub struct SnowWorkerM1 { | ||||
///基础时间 | ///基础时间 | ||||
@@ -12,7 +12,7 @@ use std::sync::Mutex; | |||||
use std::sync::Arc; | use std::sync::Arc; | ||||
use std::borrow::BorrowMut; | use std::borrow::BorrowMut; | ||||
static mut instance2: Option<Arc<Mutex<SnowWorkerM1>>> = None; | |||||
// static mut instance2: Option<Arc<Mutex<SnowWorkerM1>>> = None; | |||||
pub struct DefaultIdGenerator { | pub struct DefaultIdGenerator { | ||||
pub Worker: SnowWorkerM1, | pub Worker: SnowWorkerM1, | ||||
@@ -0,0 +1,16 @@ | |||||
# idgenerator | |||||
## 关于AutoRegisterWorkerId | |||||
这是自动注册 WorkerId 的工具。可在容器环境下集成使用。 | |||||
## 步骤集成 | |||||
全局执行一次: | |||||
1.设置Redis连接。 | |||||
2.获取 WorkerId,赋值给 IdGenerator。 | |||||
@@ -0,0 +1,7 @@ | |||||
# idgenerator | |||||
## FFI 调用 | |||||
Pyton、node.js、PHP 等可以通过 FFI 方式调用动态库生成 ID。 | |||||
这里将提供不同操作系统的动态库 |