1 điểm bởi GN⁺ 2023-09-29 | 1 bình luận | Chia sẻ qua WhatsApp
  • Deno Queues là hàng đợi phân tán serverless chạy trên Deno KV, cho phép chuyển các tác vụ tốn thời gian sang xử lý bất đồng bộ hoặc lên lịch thực thi trong tương lai
  • Nhà phát triển chỉ cần đưa thông điệp vào bằng .enqueue() và xử lý bằng .listenQueue(), không cần thiết lập hay duy trì hạ tầng hàng đợi riêng
  • Trên môi trường cục bộ, nó dùng SQLite; trên Deno Deploy, nó dùng FoundationDB, và Deploy sẽ khởi chạy V8 isolate theo yêu cầu tại thời điểm xử lý thông điệp
  • Cơ chế chuyển phát là at-least-once delivery, nên trong các tình huống lỗi hoặc retry, cùng một thông điệp có thể được xử lý nhiều lần
  • Không có phí riêng cho hàng đợi, nhưng enqueue được tính là ghi KV, còn nhận thông điệp được tính là ghi KV và một request Deno Deploy, nên cần cân nhắc cả xử lý trùng lặp lẫn cấu trúc chi phí

Deno Queues đảm nhiệm việc gì

  • Deno Queues là tính năng hàng đợi dựa trên Deno KV, cho phép chuyển một phần xử lý của ứng dụng sang tác vụ bất đồng bộ hoặc lên lịch công việc để chạy sau
  • Deno hướng tới việc giảm bớt các bước thiết lập lặp đi lặp lại và cấu hình hạ tầng trong phát triển phần mềm đám mây, đồng thời cung cấp các thành phần nền tảng để nhà phát triển có thể thiết kế, cải tiến và phát hành nhanh hơn
  • Deno KV là tùy chọn lưu trữ bền vững dựa trên FoundationDB và hiện đang ở trạng thái open beta
  • Queues cung cấp khả năng nhắn tin có thể mở rộng và quản lý xử lý nền trên Deno KV

API cơ bản và cách hoạt động

  • Deno Queues có hai API cốt lõi
    • .enqueue(): đưa thông điệp mới vào hàng đợi để chuyển ngay lập tức hoặc tại một thời điểm trong tương lai
    • .listenQueue(): dùng làm handler để nhận và xử lý thông điệp mới từ hàng đợi
  • Luồng cơ bản là mở KV bằng Deno.openKv(), gửi thông điệp Slack trong listenQueue, và chỉ định enqueue với { delay: 60000 } để thông điệp được xử lý sau 60 giây
  • Tùy theo môi trường chạy mà nơi lưu trữ sẽ khác nhau
    • Khi chạy cục bộ thì dùng SQLite
    • Khi chạy trên Deno Deploy thì dùng FoundationDB
  • Trên Deno Deploy, khi đến thời điểm có thể xử lý thông điệp, hệ thống sẽ khởi chạy V8 isolate theo yêu cầu và dispatch thông điệp
  • Mã ứng dụng chỉ cần nhận thông điệp mới trong handler listenQueue, còn phần quản lý thực thi còn lại do Deno Deploy đảm nhiệm

Bảo đảm chuyển phát và retry

  • Deno Queues bảo đảm at-least-once delivery
  • Phần lớn thông điệp được enqueue sẽ chỉ gọi handler listenQueue một lần, nhưng trong một số tình huống lỗi, cùng handler có thể bị gọi nhiều lần để bảo đảm chuyển phát
  • Vì vậy ứng dụng cần xử lý thông điệp trùng lặp một cách an toàn
  • Nếu handler listenQueue ném ra exception, runtime sẽ tự động retry lời gọi
  • Việc retry sẽ tiếp tục cho đến khi thành công hoặc đạt tới số lần retry tối đa; hiện giá trị mặc định tối đa là 5 lần
  • Thông điệp đạt tới số lần retry tối đa sẽ bị xóa

Dùng cùng KV atomic transaction

  • Deno Queues có thể kết hợp với KV atomic transactions
  • Nếu enqueue thông điệp như một phần của KV transaction, thông điệp chỉ được đưa vào hàng đợi khi toàn bộ transaction thành công
  • Luồng ví dụ là kiểm tra và cập nhật số dư của Bob và Liz, sau đó enqueue thông điệp thông báo cho cả hai
    • Dùng check(bob, liz) để kiểm tra trạng thái
    • Giảm số dư của Bob và tăng số dư của Liz
    • Dùng enqueue để thêm thông điệp thông báo lần lượt cho Liz và Bob
    • Chỉ khi commit() thành công thì toàn bộ thay đổi và enqueue mới được áp dụng
  • Có thể cập nhật trạng thái Deno KV ngay bên trong handler listenQueue
  • Nếu muốn bảo đảm cập nhật cho từng thông điệp chỉ diễn ra một lần, có thể xây dựng luồng chống xử lý trùng lặp bằng cách lưu rồi xóa nonce
    • Khi enqueue thì lưu kèm nonce
    • Khi xử lý, nếu không có nonce thì trả về ngay
    • Khi xử lý thành công thì xóa nonce và đồng thời cập nhật bộ đếm cùng trạng thái số dư

Các trường hợp sử dụng phù hợp cho hàng đợi

  • Hàng đợi giúp server chuyển xử lý bất đồng bộ và lên lịch tác vụ tương lai, nên hữu ích cho việc mở rộng ứng dụng
  • Thông báo email theo lịch

    • Khi một tác vụ do người dùng khởi tạo mất nhiều thời gian hoặc không cần chờ phản hồi hoàn tất, có thể chuyển tác vụ đó vào hàng đợi để giữ cho server hoặc ứng dụng vẫn phản hồi tốt
    • Trong ví dụ, thông điệp welcome_email được enqueue ngay lập tức, còn thông điệp survey_email được chạy trễ với { delay: 259200000 }
  • Xử lý webhook đáng tin cậy

    • Nếu không xử lý ngay request webhook mà đưa nó vào hàng đợi, có thể tách phần phản hồi khỏi phần xử lý thực tế
    • Kết hợp Oak và Queues để khi nhận request POST /webhook, nội dung request sẽ được đưa vào hàng đợi và trả về HTTP 200
    • Việc xử lý webhook thực tế sẽ được thực hiện bất đồng bộ trong listenQueue bằng processWebHook
  • Bot Slack·Discord

    • Queues cũng có thể dùng để xây dựng bot Discord hoặc Slack
    • Ví dụ ứng dụng Slack reminder là trường hợp tạo ứng dụng nhắc nhở Slack đơn giản bằng Deno Queues
    • Ví dụ bot Discord dùng Deno Queues để tạo giveaway và cho phép người dùng tham gia chỉ với một cú nhấp
    • Có thể xem thêm nhiều ví dụ sử dụng hàng đợi tại docs.deno.com

Cách tính phí

  • Deno Queues không có hạng mục tính phí chuyên biệt riêng
  • Chi phí được tính dựa trên thao tác Deno KV và request Deno Deploy
    • Enqueue thông điệp: mỗi thao tác enqueue tương ứng với 1 lần ghi KV
    • Nhận thông điệp: mỗi thông điệp được nhận sẽ phát sinh 1 lần ghi KV và 1 lần tính phí request
  • Đây là cấu trúc chỉ tính phí cho các thao tác thực sự được sử dụng

Tài liệu và lộ trình

  • Tài liệu liên quan và tham chiếu API
  • Để xây dựng web app và server có khả năng mở rộng, cần có cấu hình chuyển các tác vụ nền sang hàng đợi, nhưng cách làm trước đây thường có nhiều bước thiết lập
  • Deno Queues được tích hợp sẵn trong runtime và hoạt động trên hạ tầng Deno Deploy, cho phép sử dụng hàng đợi phân tán serverless chỉ với vài dòng mã
  • Deno Queues được đặt cùng với Deno KV, web standards APIs, npm, all-in-one modern tooling như những thành phần nhằm giúp phát triển web trở nên đơn giản và hiệu quả hơn
  • Có thể gửi phản hồi và yêu cầu tính năng qua Discord hoặc deploy_feedback issues

1 bình luận

 
GN⁺ 2023-09-29
Ý kiến trên Hacker News
  • Tôi vừa đào sâu vào bên trong phiên bản SQLite cục bộ và ghi chú lại: https://til.simonwillison.net/deno/deno-kv#user-content-deno...
    Phần thú vị nhất có lẽ là schema dùng cho tính năng này:
    CREATE TABLE queue ( ts integer not null, id text not null, data blob not null, backoff_schedule text not null, keys_if_undelivered blob not null, primary key (ts, id) );
    CREATE TABLE queue_running( deadline integer not null, id text not null, data blob not null, backoff_schedule text not null, keys_if_undelivered blob not null, primary key (deadline, id) );
    CREATE INDEX kv_expiration_ms_idx on kv (expiration_ms);

    • Tạo 2 bảng có các trường gần như giống nhau rồi di chuyển các hàng qua lại thường chẳng phải là thực hành xấu sao?
      Chẳng phải index được thiết kế chính là để dùng cho những việc như vậy à?
    • Điều đặc biệt thú vị từ góc nhìn “mô hình kinh doanh mã nguồn mở” là Deno đang đưa vào các tính năng cốt lõi của framework những chức năng mà chỉ nền tảng SaaS của chính họ mới có thể cung cấp tốt như một bản nâng cấp quy mô toàn cầu
      Khá mới mẻ nhưng cũng hơi bất an. Tất nhiên họ phải thương mại hóa, nhưng không nhất thiết phải theo cách hoàn toàn đóng; với lớp mở rộng, có lẽ họ cũng có thể dùng các giấy phép khác như BSL hoặc PolyForm
  • Mình cho rằng hướng Deno đang nhắm tới ở đây khá hướng đến tương lai
    Năm nay tôi mới bắt đầu dùng Go, và một phần của ngôn ngữ này rất giống C. Ngoài những điểm khác với C, chẳng hạn nhờ garbage collection mà có thể trả về từ hàm một giá trị trông như con trỏ được cấp phát trên stack, các tính năng tích hợp sẵn như map[string]string cũng được đưa vào rất tự nhiên. Nếu tạo một ngôn ngữ mới sau năm 2023 mà không có cú pháp tích hợp để xử lý kiểu map thì tôi thấy gần như khó chấp nhận
    Vì vậy, việc một hệ sinh thái xoay quanh web server có các thư viện, và có lẽ một ngày nào đó cả cú pháp ngôn ngữ, cho những primitive mà chúng ta thường dùng là điều có vẻ hợp lý. Tôi không nhớ nổi dự án gần đây nhất về web server phân tán mà lại không có key-value store để làm cache, cơ chế khóa, thậm chí cả queue tạm thời. Hệ thống phân tán không có key-value store lờ mờ giống một ngôn ngữ lập trình không có kiểu map, và đó thực sự là một công nghệ kiểu dao đa năng Thụy Sĩ
    Vấn đề tiềm ẩn là Deno đang đi con đường này một mình. Hiện khó chắc liệu các tính năng mới mà Deno thêm vào có được cung cấp trên các nền tảng cạnh tranh hay không, và dù API được công bố mã nguồn mở, nó vẫn nằm trong namespace Deno, nên tôi không biết liệu khi muốn đổi từ FoundationDB sang Redis trên AWS thì nó có cứ thế hoạt động hay không
    Vì vậy tôi có cảm giác muốn tránh Deno. Cú pháp và các tính năng được phơi ra thật sự hấp dẫn, nhưng tôi lo rằng sau khi đã phụ thuộc vào nó, để có thể triển khai lên nhiều hạ tầng cloud khác nhau tôi sẽ phải đại phẫu code. Nhiều khách hàng yêu cầu điều này. Ví dụ một ngày nào đó tôi muốn bán cho Oracle hay Salesforce, nhưng họ yêu cầu chạy on-premises, thì việc làm sao áp dụng key-value store mà phía đó dùng được cho khớp với tính năng package Deno sẽ đổ lên đầu tôi
    Đây là con dao hai lưỡi. Deno có thể thành công trong việc thúc đẩy tầm nhìn này đến một nhóm rộng hơn, nhưng trong thời gian tới có lẽ tôi vẫn sẽ nhìn nhận một cách thận trọng

    • Trong trường hợp này, KV Connect, giao thức kết nối từ xa, cũng đã được tài liệu hóa: https://github.com/denoland/deno/tree/main/ext/kv#kv-connect
      Tôi đã dùng thử nhẹ kv-connect-kit, một triển khai giao thức này bằng TypeScript thuần, và nó cung cấp API KV client trong bất kỳ JavaScript runtime nào. Bao gồm cả Cloudflare Workers, nơi hoàn toàn không có namespace Deno
      GitHub: https://github.com/skymethod/kv-connect-kit / npm: https://www.npmjs.com/package/kv-connect-kit / deno/x: https://deno.land/x/kv_connect_kit / demo: https://keyspace.deno.dev/
      Giao thức có vẻ hoạt động đúng như mô tả, và việc viết backend khác cũng trông khá đơn giản
    • Không đồng ý. Việc gắn runtime của ngôn ngữ với một giao diện KV cụ thể bị ràng buộc vào một dịch vụ hosting nhất định là điều ngược lại với hướng đến tương lai
      Ngành công nghệ đã tiến khá xa để thoát khỏi các stack khóa chặt vào nhà cung cấp, nhưng điều này lại gợi nhớ đến những thời kỳ đó
      Tôi không thấy khác biệt thực chất giữa việc Deno.KV được đưa vào như một phần của runtime và việc thêm import KV ở đầu file. Cách sau có thể import ở bất cứ nơi nào bạn muốn, dù là Deno hay nơi khác
      Và khả năng nhóm Deno cung cấp binding cho các ngôn ngữ khác ngoài ngôn ngữ của họ là bao nhiêu? Nếu Google bắt đầu đưa các primitive chỉ dành cho Google Cloud vào Go một cách native, bạn có gọi đó là hướng đến tương lai không?
    • Tôi thích Deno, nhưng cũng vì lý do tương tự mà trở nên thận trọng khi áp dụng. Để Deno thắng, có lẽ cả các đối thủ hosting cũng phải được hỗ trợ đầy đủ
      Đồng thời, self-hosting cũng phải ngang bằng hoặc tốt hơn các bên dẫn đầu ngành. Một con đường khác là từ bỏ self-hosting và cung cấp một giải pháp multi-cloud với biên lợi nhuận mỏng đặt trên các adapter của đối tác hosting. Khi đó Deno không cần trực tiếp cạnh tranh với tư cách nhà cung cấp hosting nữa
    • Deno chỉ đang cố cạnh tranh với các JS/TS SaaS khác bằng thứ này. Vercel/NextJS cũng có dịch vụ KV, Cloudflare cũng có, và trong các trường hợp khác thì có Firebase
      Tôi thấy đây không hẳn là hướng đến tương lai mà gần với việc kiếm tiền từ Deno dưới dạng SaaS hơn. Đó là xu hướng mà ngày nay ai trong thế giới JavaScript cũng làm với sản phẩm “cloud”: gắn framework vào rồi bán lại AWS. Vì vậy nên nó mới có bảng giá
      Nếu KV của Deno phụ thuộc vào FoundationDB, khả năng họ tích cực tạo adapter cho các cơ sở dữ liệu khác cũng có vẻ thấp. Thay đổi công nghệ cơ sở dữ liệu luôn là chuyện lớn, vì mỗi loại có mục đích sử dụng và đặc tính hiệu năng khác nhau
    • GC allowing one to return what look like stack allocated pointers from functions theo tôi không hẳn là nhờ garbage collection mà là nhờ escape analysisSSA
  • Lập luận rằng “để tận dụng hạ tầng public cloud thì phải lục lọi boilerplate code và cấu hình phức tạp, tiêu tốn nhiều thời gian và năng lượng của lập trình viên” không thuyết phục lắm
    Rốt cuộc, chúng ta đang xây dựng hạ tầng cần phải ổn định. Bỏ 30 phút để cấu hình hàng đợi SQS, một công nghệ đã được kiểm chứng, không có vẻ tệ hơn việc hoàn toàn tin vào một hàng đợi đồ chơi mà Deno tạo ra “trên SQLite / FoundationDB”. Chi phí cấu hình 30 phút và “trải nghiệm lập trình viên” tốt hơn có thật sự đáng để chấp nhận rủi ro đó không? Ngay từ đầu thì bạn cấu hình hàng đợi thường xuyên đến mức nào?

    • Tôi nghĩ điều này còn tùy tôi là kiểu người nào
      Với tư cách lập trình viên làm vì sở thích, tôi không hay dùng các nhà cung cấp lớn như AWS hay Google, vì chúng trông khá phức tạp. Nếu đã quen thì có thể cũng không tệ đến vậy
      Ngoài ra, tôi muốn mỗi dự án là một repository độc lập trên GitHub. Lý tưởng nhất là bất kỳ ai khác cũng có thể dễ dàng dựng web app dưới một domain riêng như một web app độc lập của họ. Vì tôi không muốn chịu trách nhiệm cả dữ liệu của người khác
      Điều này phần nào giống use case của Sandstorm. Hướng dẫn cài đặt kiểu “thử nghiệm cục bộ, còn nếu muốn dùng thật thì hãy tạo tài khoản Deno Deploy” nghe khá hợp lý
    • Nhiều người không có kinh nghiệm với AWS hay SQS, và ngay cả người có kinh nghiệm thì vẫn phải bận tâm. Deno chọn cách tiếp cận đầy đủ sẵn pin, để lập trình viên có thể lấy một thứ gì đó và dùng ngay
      Nếu ai đó cung cấp một thư viện tương đương cho cloud thì chắc chắn sẽ có người dùng. Với Deno, có vẻ họ đang tìm các vấn đề chung mà lập trình viên trong hệ sinh thái của họ gặp phải, rồi đóng gói một giải pháp ổn để xử lý
    • Nói cực đoan thì tôi nghĩ bây giờ tốt hơn là đừng dùng trực tiếp hàng đợi nữa. Nó giống như dùng HTTP/2 thô hoặc tự quản lý thread vậy
      Nếu dùng workflow engine trừu tượng hóa hàng đợi, bạn có thể “chỉ viết code” mà không phải quản lý task, lịch, trạng thái, retry
      https://www.inngest.com/blog/how-durable-workflow-engines-wo...
      Tuy nhiên, tôi là tác giả của workflow engine nên có thiên kiến
    • Theo lập luận đó thì về cơ bản mọi thứ mới ra đều là “dự án đồ chơi”, chỉ AWS mới được kiểm chứng, và như vậy không ai nên ra mắt sản phẩm mới cả
    • Làm sao biết đó là hàng đợi đồ chơi?
  • Theo kinh nghiệm trước đây khi xử lý “ngữ nghĩa giao ít nhất một lần” và “code của người dùng”, người dùng không hiểu đúng về giao ít nhất một lần
    Ngay khi message được gửi lại, phàn nàn của người dùng và sự cố sẽ ập đến
    Tôi nghĩ hoặc là làm được điều gần như bất khả thi và phát minh ra ngữ nghĩa giao đúng một lần, hoặc là phải luôn gửi lại 0,1% tất cả message để người dùng không thể phụ thuộc vào việc chúng chỉ được giao một lần

    • SQS thời đầu thực tế đã như vậy. Không biết có chủ ý hay không, nhưng nhờ thế tôi nhanh chóng học được rằng phải tôn trọng việc gửi lại
    • Nếu message cần phải idempotent, tôi khuyên nhất định nên tạo integration test ở phía gửi để bảo đảm điều đó
  • Hiện tôi đang dùng Deno Deploy, và với dự án làm một mình thì hiệu năng rất tốt và thật sự đơn giản
    Từ góc nhìn của người từng phát triển trên AWS trong một đội lớn, tôi rất mừng khi thấy xu hướng thoát khỏi sự phức tạp để có thể dễ dàng triển khai mà không phải nghĩ về cấu hình. DNS cũng rất đơn giản và chứng chỉ SSL tự động thì thật sự tuyệt. Tôi hoàn toàn không phàn nàn gì về hướng đi của sản phẩm này, và cũng mong chờ roadmap của họ

  • Nếu tôi không bỏ sót gì thì có vẻ mỗi instance Deno.openKv() chỉ có một hàng đợi
    Ở phiên bản cục bộ, có thể tạo nhiều hàng đợi bằng cách gọi Deno.openKv("db-2.db") với một đường dẫn file SQLite khác nhau mỗi lần, nhưng so với một nhu cầu khá phổ biến thì overhead có vẻ lớn
    Có lẽ đây là phong cách kiến trúc của Deno. Khi xây dựng ứng dụng phức tạp bằng Deno, họ kỳ vọng một cấu trúc kiểu microservice, trong đó nhiều script hoạt động cùng nhau và mỗi script có KV store cùng hàng đợi riêng của nó chăng?

    • Đúng vậy. Hiện tại chỉ có một hàng đợi duy nhất
      Một trong các core developer đã xác nhận trên Discord: https://discord.com/channels/684898665143206084/115671428253...
      Trích dẫn: “Đúng vậy. Hiện tại chỉ hỗ trợ một hàng đợi duy nhất. Tuy nhiên, có thể multiplex nhiều loại message trong một hàng đợi duy nhất.”
  • Giá cả thế nào?
    Tôi từng nghĩ Deno là một dạng thay thế cho Node.js, hay tôi đang bỏ sót gì? Có thể dùng cái này cục bộ hoặc self-host miễn phí không?

    • Cái này cũng theo cùng cách với phần còn lại của Deno KV. Phiên bản mã nguồn mở dùng SQLite, nhưng nếu triển khai lên sản phẩm cloud của Deno thì thay vào đó sẽ dùng FoundationDB độc quyền
      Vì “Queues are built on Deno KV”, lời giải thích là ở cục bộ thì dùng SQLite, còn trên Deno Deploy thì dùng FoundationDB để có độ sẵn sàng và throughput tối đa
      Tôi đã viết thêm một chút về pattern này ở đây: https://til.simonwillison.net/deno/deno-kv
    • Theo bài viết, khi phát triển cục bộ thì dùng SQLite, còn khi triển khai lên Deno thì nó trở thành một phần của tính năng do cloud cung cấp
  • Nếu các developer có đọc, tôi nghĩ với tính tiện dụng KV hiện rất tốt, phần kiểm soát truy cập có thể gây đau đầu về sau
    Tôi tò mò không biết giải pháp chỉ là “tự triển khai trong không gian người dùng và đừng tạo bug”, hay đã có kế hoạch gì chưa

    • Tôi muốn hỏi bạn đang nói đến kiểm soát truy cập ở cấp người dùng, chẳng hạn ACL cho người dùng đã xác thực, hay là thứ khác. Nếu bạn chia sẻ suy nghĩ dài hơn, tôi sẽ tiếp tục ghi nhớ mối lo này
  • Hỗ trợ Jupyter gần đây và tính năng hàng đợi lần này rất đáng mong đợi. Chúng thật sự rất hay
    Nhưng tôi không nghĩ mình sẽ viết server bằng Deno rồi đưa lên production trên server của mình. Tôi không thích serverless
    Mô hình kinh doanh của Deno và Bun được xây dựng quanh serverless, tức Deno Deploy. Và Deno Deploy lại là một runtime khác
    Điều đó thể hiện rõ ở KV và hàng đợi. Khi chạy cục bộ hoặc self-host, bạn có một phiên bản chỉ vừa đủ chạy được, đặt trên các công nghệ khác
    Tức là bạn sẽ self-host một phiên bản Deno khác với phiên bản mà phần lớn khách hàng Deno sử dụng
    Có bao nhiêu người dùng Deno để chạy server trên phần cứng của chính mình? Nếu con số đó ít, tôi thà dùng Node hơn

  • Deno thật sự rất thú vị. Mô hình kinh doanh khả thi, trải nghiệm sử dụng tốt và không có những việc cấu hình lặt vặt vô ích là những điểm tuyệt vời

    • Tôi đã thử đặt kỳ vọng vào Deno nhưng vẫn không rõ lắm. Tôi không thấy nó khác gì so với vô số thứ từng có trước đây
      Bản thân Deno về cơ bản là Node.js cộng thêm khả năng tự động biên dịch TypeScript. Nếu làm theo cách thông thường thì chỉ cần thêm một tệp cấu hình nữa mà thôi. Khi dự án ra mắt, họ nhấn mạnh mạnh mẽ việc thoát khỏi hệ sinh thái NPM lộn xộn, nhưng cuối cùng lại phải quay lại bổ sung hỗ trợ NPM, và điểm khác biệt đó cũng biến mất
      Deno Deploy giống như các dịch vụ kiểu Lambda vốn đã có hàng chục cái. Kho lưu trữ KV và giờ là hàng đợi thì tương đương với Redis, LevelDB, RocksDB, Dynamo, SQS hoặc vô số lựa chọn tương tự khác. Tôi vẫn chưa thấy tính năng nào thực sự phân biệt Deno với phần còn lại
      Nếu bạn thích việc một công ty đảm nhiệm toàn bộ runtime ngôn ngữ, hosting tính toán và kho dữ liệu, thì nó có thể hấp dẫn. Nhưng cá nhân tôi muốn tránh điều đó, đặc biệt là khi công ty đó chưa có thành tích trong lĩnh vực ấy
    • Vì sao bạn tin rằng Deno có mô hình kinh doanh khả thi?