github.com/wfusion/gofusion@v1.1.14/mq/postgres.go (about)

     1  package mq
     2  
     3  import (
     4  	"context"
     5  	"database/sql"
     6  	"fmt"
     7  
     8  	"github.com/pkg/errors"
     9  
    10  	"github.com/wfusion/gofusion/common/infra/watermill"
    11  	"github.com/wfusion/gofusion/common/utils"
    12  	"github.com/wfusion/gofusion/config"
    13  	"github.com/wfusion/gofusion/db"
    14  
    15  	millSql "github.com/wfusion/gofusion/common/infra/watermill/pubsub/sql"
    16  )
    17  
    18  func newPostgres(ctx context.Context, appName, name string, conf *Conf, logger watermill.LoggerAdapter) (
    19  	pub Publisher, sub Subscriber) {
    20  	instance := db.Use(ctx, conf.Endpoint.Instance, db.AppName(appName))
    21  	cli := utils.Must(instance.GetProxy().DB())
    22  	if conf.Producer {
    23  		pub = newPostgresPublisher(ctx, appName, name, conf, logger, cli)
    24  	}
    25  
    26  	if conf.Consumer {
    27  		sub = newPostgresSubscriber(ctx, appName, name, conf, logger, cli)
    28  	}
    29  
    30  	return
    31  }
    32  
    33  type postgresPublisher struct {
    34  	*abstractMQ
    35  	publisher *millSql.Publisher
    36  }
    37  
    38  func newPostgresPublisher(ctx context.Context, appName, name string, conf *Conf, logger watermill.LoggerAdapter,
    39  	cli *sql.DB) Publisher {
    40  	cfg := millSql.PublisherConfig{
    41  		SchemaAdapter: millSql.DefaultPostgreSQLSchema{
    42  			GenerateMessagesTableName: func(topic string) string {
    43  				return fmt.Sprintf("%s_%s", conf.MessageScheme, topic)
    44  			},
    45  			SubscribeBatchSize: conf.ConsumerConcurrency,
    46  		},
    47  		AutoInitializeSchema: true,
    48  		AppID:                config.Use(appName).AppName(),
    49  	}
    50  
    51  	pub, err := millSql.NewPublisher(cli, cfg, logger)
    52  	if err != nil {
    53  		panic(errors.Wrapf(err, "initialize mq component postgres publisher failed: %s", err))
    54  	}
    55  
    56  	return &postgresPublisher{
    57  		abstractMQ: newPub(ctx, pub, appName, name, conf, logger),
    58  		publisher:  pub,
    59  	}
    60  }
    61  
    62  func (p *postgresPublisher) close() (err error) {
    63  	return p.publisher.Close()
    64  }
    65  
    66  type postgresSubscriber struct {
    67  	*abstractMQ
    68  	subscriber *millSql.Subscriber
    69  }
    70  
    71  func newPostgresSubscriber(ctx context.Context, appName, name string, conf *Conf, logger watermill.LoggerAdapter,
    72  	cli *sql.DB) Subscriber {
    73  	cfg := millSql.SubscriberConfig{
    74  		ConsumerGroup:  conf.ConsumerGroup,
    75  		PollInterval:   0,
    76  		ResendInterval: 0,
    77  		RetryInterval:  0,
    78  		BackoffManager: nil,
    79  		SchemaAdapter: millSql.DefaultPostgreSQLSchema{
    80  			GenerateMessagesTableName: func(topic string) string {
    81  				return fmt.Sprintf("%s_%s", conf.MessageScheme, topic)
    82  			},
    83  			SubscribeBatchSize: conf.ConsumerConcurrency, // fetch how many rows per query
    84  		},
    85  		OffsetsAdapter: millSql.DefaultPostgreSQLOffsetsAdapter{
    86  			GenerateMessagesOffsetsTableName: func(topic string) string {
    87  				return fmt.Sprintf("%s_offsets_%s", conf.MessageScheme, topic)
    88  			},
    89  		},
    90  		InitializeSchema:  true,
    91  		DisablePersistent: !conf.Persistent,
    92  	}
    93  
    94  	sub, err := millSql.NewSubscriber(cli, cfg, logger)
    95  	if err != nil {
    96  		panic(errors.Wrapf(err, "initialize mq component mysql subscriber failed: %s", err))
    97  	}
    98  
    99  	return &postgresSubscriber{
   100  		abstractMQ: newSub(ctx, sub, appName, name, conf, logger),
   101  		subscriber: sub,
   102  	}
   103  }
   104  
   105  func (p *postgresSubscriber) close() (err error) {
   106  	return p.subscriber.Close()
   107  }