getUpHost method

  1. @override
Future<String> getUpHost({
  1. required String accessKey,
  2. required String bucket,
})
override

Implementation

@override
Future<String> getUpHost({
  required String accessKey,
  required String bucket,
}) async {
  // 解冻需要被解冻的 host
  _frozenUpDomains.removeWhere((domain) => !domain.isFrozen());

  final upDomains = <_Domain>[];
  if ('$accessKey:$bucket' == _cacheKey && _stashedUpDomains.isNotEmpty) {
    upDomains.addAll(_stashedUpDomains);
  } else {
    final url =
        '$protocol://api.qiniu.com/v4/query?ak=$accessKey&bucket=$bucket';

    final res = await _http.get<Map>(url);

    final hosts = res.data!['hosts']
        .map((dynamic json) => _Host.fromJson(json as Map))
        .cast<_Host>()
        .toList() as List<_Host>;

    for (var host in hosts) {
      final domainList = host.up['domains'].cast<String>() as List<String>;
      final domains = domainList.map((domain) => _Domain(domain));
      upDomains.addAll(domains);
    }

    _cacheKey = '$accessKey:$bucket';
    _stashedUpDomains.addAll(upDomains);
  }

  // 每次都从头遍历一遍,最合适的 host 总是会排在最前面
  for (var index = 0; index < upDomains.length; index++) {
    final availableDomain = upDomains.elementAt(index);
    // 检查看起来可用的 host 是否之前被冻结过
    final frozen = isFrozen('$protocol://${availableDomain.value}');

    if (!frozen) {
      return '$protocol://${availableDomain.value}';
    }
  }
  // 全部被冻结,几乎不存在的情况
  throw StorageError(
    type: StorageErrorType.NO_AVAILABLE_HOST,
    message: '没有可用的上传域名',
  );
}