go.temporal.io/server@v1.23.0/common/persistence/sql/sqlplugin/postgresql/queue.go (about) 1 // The MIT License 2 // 3 // Copyright (c) 2020 Temporal Technologies Inc. All rights reserved. 4 // 5 // Copyright (c) 2020 Uber Technologies, Inc. 6 // 7 // Permission is hereby granted, free of charge, to any person obtaining a copy 8 // of this software and associated documentation files (the "Software"), to deal 9 // in the Software without restriction, including without limitation the rights 10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 // copies of the Software, and to permit persons to whom the Software is 12 // furnished to do so, subject to the following conditions: 13 // 14 // The above copyright notice and this permission notice shall be included in 15 // all copies or substantial portions of the Software. 16 // 17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 // THE SOFTWARE. 24 25 package postgresql 26 27 import ( 28 "context" 29 "database/sql" 30 31 "go.temporal.io/server/common/persistence" 32 "go.temporal.io/server/common/persistence/sql/sqlplugin" 33 ) 34 35 const ( 36 templateEnqueueMessageQuery = `INSERT INTO queue (queue_type, message_id, message_payload, message_encoding) VALUES(:queue_type, :message_id, :message_payload, :message_encoding)` 37 templateGetMessageQuery = `SELECT message_id, message_payload, message_encoding FROM queue WHERE queue_type = $1 and message_id = $2` 38 templateGetMessagesQuery = `SELECT message_id, message_payload, message_encoding FROM queue WHERE queue_type = $1 and message_id > $2 and message_id <= $3 ORDER BY message_id ASC LIMIT $4` 39 templateDeleteMessageQuery = `DELETE FROM queue WHERE queue_type = $1 and message_id = $2` 40 templateRangeDeleteMessagesQuery = `DELETE FROM queue WHERE queue_type = $1 and message_id > $2 and message_id <= $3` 41 42 templateGetLastMessageIDQuery = `SELECT message_id FROM queue WHERE message_id >= (SELECT message_id FROM queue WHERE queue_type=$1 ORDER BY message_id DESC LIMIT 1) FOR UPDATE` 43 44 templateCreateQueueMetadataQuery = `INSERT INTO queue_metadata (queue_type, data, data_encoding, version) VALUES(:queue_type, :data, :data_encoding, :version)` 45 templateUpdateQueueMetadataQuery = `UPDATE queue_metadata SET data = :data, data_encoding = :data_encoding, version = :version+1 WHERE queue_type = :queue_type and version = :version` 46 templateGetQueueMetadataQuery = `SELECT data, data_encoding, version from queue_metadata WHERE queue_type = $1` 47 templateLockQueueMetadataQuery = templateGetQueueMetadataQuery + " FOR UPDATE" 48 ) 49 50 // InsertIntoMessages inserts a new row into queue table 51 func (pdb *db) InsertIntoMessages( 52 ctx context.Context, 53 row []sqlplugin.QueueMessageRow, 54 ) (sql.Result, error) { 55 return pdb.conn.NamedExecContext(ctx, 56 templateEnqueueMessageQuery, 57 row, 58 ) 59 } 60 61 func (pdb *db) SelectFromMessages( 62 ctx context.Context, 63 filter sqlplugin.QueueMessagesFilter, 64 ) ([]sqlplugin.QueueMessageRow, error) { 65 var rows []sqlplugin.QueueMessageRow 66 err := pdb.conn.SelectContext(ctx, 67 &rows, 68 templateGetMessageQuery, 69 filter.QueueType, 70 filter.MessageID, 71 ) 72 return rows, err 73 } 74 75 func (pdb *db) RangeSelectFromMessages( 76 ctx context.Context, 77 filter sqlplugin.QueueMessagesRangeFilter, 78 ) ([]sqlplugin.QueueMessageRow, error) { 79 var rows []sqlplugin.QueueMessageRow 80 err := pdb.conn.SelectContext(ctx, 81 &rows, 82 templateGetMessagesQuery, 83 filter.QueueType, 84 filter.MinMessageID, 85 filter.MaxMessageID, 86 filter.PageSize, 87 ) 88 return rows, err 89 } 90 91 // DeleteFromMessages deletes message with a messageID from the queue 92 func (pdb *db) DeleteFromMessages( 93 ctx context.Context, 94 filter sqlplugin.QueueMessagesFilter, 95 ) (sql.Result, error) { 96 return pdb.conn.ExecContext(ctx, 97 templateDeleteMessageQuery, 98 filter.QueueType, 99 filter.MessageID, 100 ) 101 } 102 103 // RangeDeleteFromMessages deletes messages before messageID from the queue 104 func (pdb *db) RangeDeleteFromMessages( 105 ctx context.Context, 106 filter sqlplugin.QueueMessagesRangeFilter, 107 ) (sql.Result, error) { 108 return pdb.conn.ExecContext(ctx, 109 templateRangeDeleteMessagesQuery, 110 filter.QueueType, 111 filter.MinMessageID, 112 filter.MaxMessageID, 113 ) 114 } 115 116 // GetLastEnqueuedMessageIDForUpdate returns the last enqueued message ID 117 func (pdb *db) GetLastEnqueuedMessageIDForUpdate( 118 ctx context.Context, 119 queueType persistence.QueueType, 120 ) (int64, error) { 121 var lastMessageID int64 122 err := pdb.conn.GetContext(ctx, 123 &lastMessageID, 124 templateGetLastMessageIDQuery, 125 queueType, 126 ) 127 return lastMessageID, err 128 } 129 130 func (pdb *db) InsertIntoQueueMetadata( 131 ctx context.Context, 132 row *sqlplugin.QueueMetadataRow, 133 ) (sql.Result, error) { 134 return pdb.conn.NamedExecContext(ctx, 135 templateCreateQueueMetadataQuery, 136 row, 137 ) 138 } 139 140 func (pdb *db) UpdateQueueMetadata( 141 ctx context.Context, 142 row *sqlplugin.QueueMetadataRow, 143 ) (sql.Result, error) { 144 return pdb.conn.NamedExecContext(ctx, 145 templateUpdateQueueMetadataQuery, 146 row, 147 ) 148 } 149 150 func (pdb *db) SelectFromQueueMetadata( 151 ctx context.Context, 152 filter sqlplugin.QueueMetadataFilter, 153 ) (*sqlplugin.QueueMetadataRow, error) { 154 var row sqlplugin.QueueMetadataRow 155 err := pdb.conn.GetContext(ctx, 156 &row, 157 templateGetQueueMetadataQuery, 158 filter.QueueType, 159 ) 160 if err != nil { 161 return nil, err 162 } 163 return &row, err 164 } 165 166 func (pdb *db) LockQueueMetadata( 167 ctx context.Context, 168 filter sqlplugin.QueueMetadataFilter, 169 ) (*sqlplugin.QueueMetadataRow, error) { 170 var row sqlplugin.QueueMetadataRow 171 err := pdb.conn.GetContext(ctx, 172 &row, 173 templateLockQueueMetadataQuery, 174 filter.QueueType, 175 ) 176 if err != nil { 177 return nil, err 178 } 179 return &row, err 180 }