Commit 94cca7a5 authored by Cranky Kernel's avatar Cranky Kernel

history: paginate the results

parent 3c0c9e42
Pipeline #53988411 passed with stage
in 12 minutes and 44 seconds
......@@ -27,6 +27,8 @@
- Provide visiable health status in the
UI. https://gitlab.com/crankykernel/maker/issues/42
- Add simple Binance balance view.
- Paginate trade history view. Too many trades can harm performance,
server side and in the browser.
[Full Changelog](https://gitlab.com/crankykernel/maker/compare/0.3.2...master)
......
......@@ -264,6 +264,8 @@ func DbGetTradeByID(tradeId string) (*types.TradeState, error) {
type TradeQueryOptions struct {
IsClosed bool
Offset int64
Limit int64
}
func DbQueryTrades(options TradeQueryOptions) ([]types.TradeState, error) {
......@@ -279,6 +281,11 @@ func DbQueryTrades(options TradeQueryOptions) ([]types.TradeState, error) {
sql = fmt.Sprintf("%s WHERE %s", sql, strings.Join(where, "AND "))
}
sql = fmt.Sprintf("%s ORDER BY json_extract(binance_trade.data, '$.CloseTime') DESC ", sql)
sql = fmt.Sprintf("%s LIMIT %d OFFSET %d ", sql, options.Limit, options.Offset)
log.Printf("%s", sql)
rows, err := db.Query(sql)
if err != nil {
return nil, err
......
......@@ -530,16 +530,36 @@ func staticAssetHandler() http.HandlerFunc {
}
}
func queryTradesHandler(w http.ResponseWriter, r *http.Request) {
// AKA trade history.
func tradeQueryHandler(w http.ResponseWriter, r *http.Request) {
queryOptions := db.TradeQueryOptions{}
queryOptions.IsClosed = true
queryOptions.Offset = 0
queryOptions.Limit = 50
if r.FormValue("offset") != "" {
offset, err := strconv.ParseInt(r.FormValue("offset"), 10, 64)
if err != nil {
log.WithError(err).WithFields(log.Fields{
"handler": "tradeQuery",
"offset": r.FormValue("offset"),
}).Errorf("Failed to parse offset as int64")
} else {
queryOptions.Offset = offset
}
}
log.Println(r.FormValue("offset"))
log.Println(r.FormValue("limit"))
s := time.Now()
trades, err := db.DbQueryTrades(queryOptions)
if err != nil {
log.WithError(err).Error("Failed to load trades from database.")
return
}
e := time.Now().Sub(s)
log.Printf("Found %d trades in %v", len(trades), e)
WriteJsonResponse(w, http.StatusOK, trades)
}
......
......@@ -272,7 +272,7 @@ func ServerMain() {
binanceProxyHandlers := NewBinanceProxyHandlers()
binanceProxyHandlers.RegisterHandlers(router)
router.HandleFunc("/api/trade/query", queryTradesHandler).
router.HandleFunc("/api/trade/query", tradeQueryHandler).
Methods("GET")
router.HandleFunc("/api/trade/{tradeId}",
getTradeHandler).Methods("GET")
......
......@@ -239,13 +239,13 @@ Loop:
}
type MakerMessage struct {
Type MakerMessageType `json:"messageType"`
Type MakerMessageType `json:"messageType"`
Trade *types.TradeState `json:"trade,omitempty"`
TradeID string `json:"tradeId,omitempty"`
TradeID string `json:"tradeId,omitempty"`
BinanceAggTrade *binanceapi.StreamAggTrade `json:"binanceAggTrade,omitempty"`
BinanceOutboundAccountInfo *binanceapi.StreamOutboundAccountInfo `json:"binanceOutboundAccountInfo,omitempty"`
Notice *clientnotificationservice.Notice `json:"notice,omitempty"`
Health *healthservice.State `json:"health,omitempty"`
Notice *clientnotificationservice.Notice `json:"notice,omitempty"`
Health *healthservice.State `json:"health,omitempty"`
}
type MakerMessageType string
......
<div class="container-fluid">
<br/>
<nav class="navbar navbar-expand navbar-light bg-light">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
{{ (page * pageSize) + 1 }}
to
{{ (page * pageSize) + trades.length }}
of
{{ trades.length < pageSize ? page * pageSize + trades.length : ((page * pageSize) + trades.length) + '+' }}
</li>
</ul>
<div class="btn-group" role="group">
<button type="button"
[attr.disabled]="page === 0 ? '' : null"
class="btn btn-outline-primary"
(click)="gotoPreviousPage()"
>Previous
</button>
<button type="button"
class="btn btn-outline-primary"
[attr.disabled]="trades.length < pageSize ? '' : null"
(click)="gotoNextPage()"
>Next
</button>
</div>
<button class="btn btn-outline-secondary ml-2" (click)="refresh()">Refresh</button>
</nav>
<table class="table table-sm">
<tr>
......
......@@ -13,37 +13,72 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import {AfterViewInit, Component, OnInit} from '@angular/core';
import {Component, OnInit} from '@angular/core';
import {TradeState} from '../maker.service';
import {AppTradeState, toAppTradeState} from '../trade-table/trade-table.component';
import {toAppTradeState} from '../trade-table/trade-table.component';
import {MakerApiService} from "../maker-api.service";
import {ActivatedRoute, Router} from "@angular/router";
@Component({
selector: 'app-history',
templateUrl: './history.component.html',
styleUrls: ['./history.component.scss']
})
export class HistoryComponent implements OnInit, AfterViewInit {
export class HistoryComponent implements OnInit {
trades: TradeState[] = [];
constructor(private makerApi: MakerApiService) {
page: number = 0;
pageSize = 50;
constructor(private makerApi: MakerApiService,
private route: ActivatedRoute,
private router: Router) {
}
ngOnInit() {
this.route.params.subscribe((params) => {
console.log(params);
if (params.page !== undefined) {
this.page = +params.page;
}
this.refresh()
});
}
ngAfterViewInit() {
this.makerApi.get("/api/trade/query")
.subscribe((trades: TradeState[]) => {
this.trades = trades.map((trade) => {
refresh() {
let offset = this.page * this.pageSize;
console.log(offset);
this.makerApi.get("/api/trade/query", {
params: {
offset: offset,
limit: this.pageSize,
}
}).subscribe((trades: TradeState[]) => {
this.trades = trades
.map((trade) => {
return toAppTradeState(trade);
}).sort(this.sort);
});
});
});
}
gotoPreviousPage() {
let page = this.page < 1 ? 0 : this.page - 1;
let params = {
page: page,
};
this.router.navigate([".", params], {
queryParamsHandling: "merge",
});
}
private sort(a: AppTradeState, b: AppTradeState) {
return new Date(b.OpenTime).getTime() -
new Date(a.OpenTime).getTime();
gotoNextPage() {
let params = {
page: this.page + 1,
};
this.router.navigate([".", params], {
queryParamsHandling: "merge",
});
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment